mirror of
https://github.com/svg/svgo.git
synced 2025-07-31 07:44:22 +03:00
chore: convert project to us ECMAScript modules (preserving CJS compatibility) (#1905)
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2021
|
||||
"ecmaVersion": 2021,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
@ -8,12 +9,6 @@
|
||||
},
|
||||
"extends": ["eslint:recommended"],
|
||||
"overrides": [
|
||||
{
|
||||
"files": ["rollup.config.js", "**/*.mjs"],
|
||||
"parserOptions": {
|
||||
"sourceType": "module"
|
||||
}
|
||||
},
|
||||
{
|
||||
"files": ["**/*.cjs"],
|
||||
"parserOptions": {
|
||||
|
3
.github/workflows/main.yml
vendored
3
.github/workflows/main.yml
vendored
@ -47,7 +47,6 @@ jobs:
|
||||
- 20
|
||||
- 18
|
||||
- 16
|
||||
- 14
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
@ -61,4 +60,4 @@ jobs:
|
||||
- run: yarn install
|
||||
- run: yarn playwright install --with-deps chromium
|
||||
- run: yarn test
|
||||
- run: yarn test-browser
|
||||
- run: yarn test-bundles
|
||||
|
12
README.md
12
README.md
@ -54,7 +54,7 @@ SVGO reads the configuration from `svgo.config.js` or the `--config path/to/conf
|
||||
**`svgo.config.js`**
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
export default {
|
||||
multipass: false, // boolean
|
||||
datauri: 'base64', // 'base64'|'enc'|'unenc'
|
||||
js2svg: {
|
||||
@ -83,7 +83,7 @@ Instead of configuring SVGO from scratch, you can tweak the default preset to su
|
||||
**`svgo.config.js`**
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
export default {
|
||||
plugins: [
|
||||
{
|
||||
name: 'preset-default',
|
||||
@ -112,9 +112,9 @@ You can also specify custom plugins:
|
||||
**`svgo.config.js`**
|
||||
|
||||
```js
|
||||
const importedPlugin = require('./imported-plugin');
|
||||
import importedPlugin from './imported-plugin';
|
||||
|
||||
module.exports = {
|
||||
export default {
|
||||
plugins: [
|
||||
// plugin imported from another JavaScript file
|
||||
importedPlugin,
|
||||
@ -140,7 +140,7 @@ SVGO provides a few low level utilities.
|
||||
The core of SVGO is `optimize` function.
|
||||
|
||||
```js
|
||||
const { optimize } = require('svgo');
|
||||
import { optimize } from 'svgo';
|
||||
|
||||
const result = optimize(svgString, {
|
||||
path: 'path-to.svg', // recommended
|
||||
@ -155,7 +155,7 @@ const optimizedSvgString = result.data;
|
||||
If you write a tool on top of SVGO you may want to resolve the `svgo.config.js` file.
|
||||
|
||||
```js
|
||||
const { loadConfig } = require('svgo');
|
||||
import { loadConfig } from 'svgo';
|
||||
|
||||
const config = await loadConfig();
|
||||
```
|
||||
|
@ -1,8 +1,8 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const colors = require('picocolors');
|
||||
const { program } = require('commander');
|
||||
const makeProgram = require('../lib/svgo/coa');
|
||||
import colors from 'picocolors';
|
||||
import { program } from 'commander';
|
||||
import makeProgram from '../lib/svgo/coa.js';
|
||||
makeProgram(program);
|
||||
program.parseAsync(process.argv).catch((error) => {
|
||||
console.error(colors.red(error.stack));
|
162
lib/builtin.js
162
lib/builtin.js
@ -1,57 +1,109 @@
|
||||
'use strict';
|
||||
import presetDefault from '../plugins/preset-default.js';
|
||||
import * as addAttributesToSVGElement from '../plugins/addAttributesToSVGElement.js';
|
||||
import * as addClassesToSVGElement from '../plugins/addClassesToSVGElement.js';
|
||||
import * as cleanupAttrs from '../plugins/cleanupAttrs.js';
|
||||
import * as cleanupEnableBackground from '../plugins/cleanupEnableBackground.js';
|
||||
import * as cleanupIds from '../plugins/cleanupIds.js';
|
||||
import * as cleanupListOfValues from '../plugins/cleanupListOfValues.js';
|
||||
import * as cleanupNumericValues from '../plugins/cleanupNumericValues.js';
|
||||
import * as collapseGroups from '../plugins/collapseGroups.js';
|
||||
import * as convertColors from '../plugins/convertColors.js';
|
||||
import * as convertEllipseToCircle from '../plugins/convertEllipseToCircle.js';
|
||||
import * as convertOneStopGradients from '../plugins/convertOneStopGradients.js';
|
||||
import * as convertPathData from '../plugins/convertPathData.js';
|
||||
import * as convertShapeToPath from '../plugins/convertShapeToPath.js';
|
||||
import * as convertStyleToAttrs from '../plugins/convertStyleToAttrs.js';
|
||||
import * as convertTransform from '../plugins/convertTransform.js';
|
||||
import * as mergeStyles from '../plugins/mergeStyles.js';
|
||||
import * as inlineStyles from '../plugins/inlineStyles.js';
|
||||
import * as mergePaths from '../plugins/mergePaths.js';
|
||||
import * as minifyStyles from '../plugins/minifyStyles.js';
|
||||
import * as moveElemsAttrsToGroup from '../plugins/moveElemsAttrsToGroup.js';
|
||||
import * as moveGroupAttrsToElems from '../plugins/moveGroupAttrsToElems.js';
|
||||
import * as prefixIds from '../plugins/prefixIds.js';
|
||||
import * as removeAttributesBySelector from '../plugins/removeAttributesBySelector.js';
|
||||
import * as removeAttrs from '../plugins/removeAttrs.js';
|
||||
import * as removeComments from '../plugins/removeComments.js';
|
||||
import * as removeDesc from '../plugins/removeDesc.js';
|
||||
import * as removeDimensions from '../plugins/removeDimensions.js';
|
||||
import * as removeDoctype from '../plugins/removeDoctype.js';
|
||||
import * as removeEditorsNSData from '../plugins/removeEditorsNSData.js';
|
||||
import * as removeElementsByAttr from '../plugins/removeElementsByAttr.js';
|
||||
import * as removeEmptyAttrs from '../plugins/removeEmptyAttrs.js';
|
||||
import * as removeEmptyContainers from '../plugins/removeEmptyContainers.js';
|
||||
import * as removeEmptyText from '../plugins/removeEmptyText.js';
|
||||
import * as removeHiddenElems from '../plugins/removeHiddenElems.js';
|
||||
import * as removeMetadata from '../plugins/removeMetadata.js';
|
||||
import * as removeNonInheritableGroupAttrs from '../plugins/removeNonInheritableGroupAttrs.js';
|
||||
import * as removeOffCanvasPaths from '../plugins/removeOffCanvasPaths.js';
|
||||
import * as removeRasterImages from '../plugins/removeRasterImages.js';
|
||||
import * as removeScriptElement from '../plugins/removeScriptElement.js';
|
||||
import * as removeStyleElement from '../plugins/removeStyleElement.js';
|
||||
import * as removeTitle from '../plugins/removeTitle.js';
|
||||
import * as removeUnknownsAndDefaults from '../plugins/removeUnknownsAndDefaults.js';
|
||||
import * as removeUnusedNS from '../plugins/removeUnusedNS.js';
|
||||
import * as removeUselessDefs from '../plugins/removeUselessDefs.js';
|
||||
import * as removeUselessStrokeAndFill from '../plugins/removeUselessStrokeAndFill.js';
|
||||
import * as removeViewBox from '../plugins/removeViewBox.js';
|
||||
import * as removeXlink from '../plugins/removeXlink.js';
|
||||
import * as removeXMLNS from '../plugins/removeXMLNS.js';
|
||||
import * as removeXMLProcInst from '../plugins/removeXMLProcInst.js';
|
||||
import * as reusePaths from '../plugins/reusePaths.js';
|
||||
import * as sortAttrs from '../plugins/sortAttrs.js';
|
||||
import * as sortDefsChildren from '../plugins/sortDefsChildren.js';
|
||||
|
||||
exports.builtin = [
|
||||
require('../plugins/preset-default.js'),
|
||||
require('../plugins/addAttributesToSVGElement.js'),
|
||||
require('../plugins/addClassesToSVGElement.js'),
|
||||
require('../plugins/cleanupAttrs.js'),
|
||||
require('../plugins/cleanupEnableBackground.js'),
|
||||
require('../plugins/cleanupIds.js'),
|
||||
require('../plugins/cleanupListOfValues.js'),
|
||||
require('../plugins/cleanupNumericValues.js'),
|
||||
require('../plugins/collapseGroups.js'),
|
||||
require('../plugins/convertColors.js'),
|
||||
require('../plugins/convertEllipseToCircle.js'),
|
||||
require('../plugins/convertOneStopGradients.js'),
|
||||
require('../plugins/convertPathData.js'),
|
||||
require('../plugins/convertShapeToPath.js'),
|
||||
require('../plugins/convertStyleToAttrs.js'),
|
||||
require('../plugins/convertTransform.js'),
|
||||
require('../plugins/mergeStyles.js'),
|
||||
require('../plugins/inlineStyles.js'),
|
||||
require('../plugins/mergePaths.js'),
|
||||
require('../plugins/minifyStyles.js'),
|
||||
require('../plugins/moveElemsAttrsToGroup.js'),
|
||||
require('../plugins/moveGroupAttrsToElems.js'),
|
||||
require('../plugins/prefixIds.js'),
|
||||
require('../plugins/removeAttributesBySelector.js'),
|
||||
require('../plugins/removeAttrs.js'),
|
||||
require('../plugins/removeComments.js'),
|
||||
require('../plugins/removeDesc.js'),
|
||||
require('../plugins/removeDimensions.js'),
|
||||
require('../plugins/removeDoctype.js'),
|
||||
require('../plugins/removeEditorsNSData.js'),
|
||||
require('../plugins/removeElementsByAttr.js'),
|
||||
require('../plugins/removeEmptyAttrs.js'),
|
||||
require('../plugins/removeEmptyContainers.js'),
|
||||
require('../plugins/removeEmptyText.js'),
|
||||
require('../plugins/removeHiddenElems.js'),
|
||||
require('../plugins/removeMetadata.js'),
|
||||
require('../plugins/removeNonInheritableGroupAttrs.js'),
|
||||
require('../plugins/removeOffCanvasPaths.js'),
|
||||
require('../plugins/removeRasterImages.js'),
|
||||
require('../plugins/removeScriptElement.js'),
|
||||
require('../plugins/removeStyleElement.js'),
|
||||
require('../plugins/removeTitle.js'),
|
||||
require('../plugins/removeUnknownsAndDefaults.js'),
|
||||
require('../plugins/removeUnusedNS.js'),
|
||||
require('../plugins/removeUselessDefs.js'),
|
||||
require('../plugins/removeUselessStrokeAndFill.js'),
|
||||
require('../plugins/removeViewBox.js'),
|
||||
require('../plugins/removeXlink.js'),
|
||||
require('../plugins/removeXMLNS.js'),
|
||||
require('../plugins/removeXMLProcInst.js'),
|
||||
require('../plugins/reusePaths.js'),
|
||||
require('../plugins/sortAttrs.js'),
|
||||
require('../plugins/sortDefsChildren.js'),
|
||||
export const builtin = [
|
||||
presetDefault,
|
||||
addAttributesToSVGElement,
|
||||
addClassesToSVGElement,
|
||||
cleanupAttrs,
|
||||
cleanupEnableBackground,
|
||||
cleanupIds,
|
||||
cleanupListOfValues,
|
||||
cleanupNumericValues,
|
||||
collapseGroups,
|
||||
convertColors,
|
||||
convertEllipseToCircle,
|
||||
convertOneStopGradients,
|
||||
convertPathData,
|
||||
convertShapeToPath,
|
||||
convertStyleToAttrs,
|
||||
convertTransform,
|
||||
mergeStyles,
|
||||
inlineStyles,
|
||||
mergePaths,
|
||||
minifyStyles,
|
||||
moveElemsAttrsToGroup,
|
||||
moveGroupAttrsToElems,
|
||||
prefixIds,
|
||||
removeAttributesBySelector,
|
||||
removeAttrs,
|
||||
removeComments,
|
||||
removeDesc,
|
||||
removeDimensions,
|
||||
removeDoctype,
|
||||
removeEditorsNSData,
|
||||
removeElementsByAttr,
|
||||
removeEmptyAttrs,
|
||||
removeEmptyContainers,
|
||||
removeEmptyText,
|
||||
removeHiddenElems,
|
||||
removeMetadata,
|
||||
removeNonInheritableGroupAttrs,
|
||||
removeOffCanvasPaths,
|
||||
removeRasterImages,
|
||||
removeScriptElement,
|
||||
removeStyleElement,
|
||||
removeTitle,
|
||||
removeUnknownsAndDefaults,
|
||||
removeUnusedNS,
|
||||
removeUselessDefs,
|
||||
removeUselessStrokeAndFill,
|
||||
removeViewBox,
|
||||
removeXlink,
|
||||
removeXMLNS,
|
||||
removeXMLProcInst,
|
||||
reusePaths,
|
||||
sortAttrs,
|
||||
sortDefsChildren,
|
||||
];
|
||||
|
@ -1,21 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types').XastNode} XastNode
|
||||
* @typedef {import('./types').XastInstruction} XastInstruction
|
||||
* @typedef {import('./types').XastDoctype} XastDoctype
|
||||
* @typedef {import('./types').XastComment} XastComment
|
||||
* @typedef {import('./types').XastRoot} XastRoot
|
||||
* @typedef {import('./types').XastElement} XastElement
|
||||
* @typedef {import('./types').XastCdata} XastCdata
|
||||
* @typedef {import('./types').XastText} XastText
|
||||
* @typedef {import('./types').XastParent} XastParent
|
||||
* @typedef {import('./types').XastChild} XastChild
|
||||
* @typedef {import('./types.js').XastNode} XastNode
|
||||
* @typedef {import('./types.js').XastInstruction} XastInstruction
|
||||
* @typedef {import('./types.js').XastDoctype} XastDoctype
|
||||
* @typedef {import('./types.js').XastComment} XastComment
|
||||
* @typedef {import('./types.js').XastRoot} XastRoot
|
||||
* @typedef {import('./types.js').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastCdata} XastCdata
|
||||
* @typedef {import('./types.js').XastText} XastText
|
||||
* @typedef {import('./types.js').XastParent} XastParent
|
||||
* @typedef {import('./types.js').XastChild} XastChild
|
||||
*/
|
||||
|
||||
// @ts-ignore sax will be replaced with something else later
|
||||
const SAX = require('@trysound/sax');
|
||||
const { textElems } = require('../plugins/_collections');
|
||||
import SAX from '@trysound/sax';
|
||||
import { textElems } from '../plugins/_collections.js';
|
||||
|
||||
class SvgoParserError extends Error {
|
||||
/**
|
||||
@ -89,7 +87,7 @@ const config = {
|
||||
*
|
||||
* @type {(data: string, from?: string) => XastRoot}
|
||||
*/
|
||||
const parseSvg = (data, from) => {
|
||||
export const parseSvg = (data, from) => {
|
||||
const sax = SAX.parser(config.strict, config);
|
||||
/**
|
||||
* @type {XastRoot}
|
||||
@ -259,4 +257,3 @@ const parseSvg = (data, from) => {
|
||||
sax.write(data).close();
|
||||
return root;
|
||||
};
|
||||
exports.parseSvg = parseSvg;
|
||||
|
18
lib/path.js
18
lib/path.js
@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const { removeLeadingZero, toFixed } = require('./svgo/tools');
|
||||
import { removeLeadingZero, toFixed } from './svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types').PathDataItem} PathDataItem
|
||||
* @typedef {import('./types').PathDataCommand} PathDataCommand
|
||||
* @typedef {import('./types.js').PathDataItem} PathDataItem
|
||||
* @typedef {import('./types.js').PathDataCommand} PathDataCommand
|
||||
*/
|
||||
|
||||
// Based on https://www.w3.org/TR/SVG11/paths.html#PathDataBNF
|
||||
@ -137,7 +135,7 @@ const readNumber = (string, cursor) => {
|
||||
/**
|
||||
* @type {(string: string) => PathDataItem[]}
|
||||
*/
|
||||
const parsePathData = (string) => {
|
||||
export const parsePathData = (string) => {
|
||||
/**
|
||||
* @type {PathDataItem[]}
|
||||
*/
|
||||
@ -240,7 +238,6 @@ const parsePathData = (string) => {
|
||||
}
|
||||
return pathData;
|
||||
};
|
||||
exports.parsePathData = parsePathData;
|
||||
|
||||
/**
|
||||
* @type {(number: number, precision?: number) => {
|
||||
@ -316,7 +313,11 @@ const stringifyArgs = (command, args, precision, disableSpaceAfterFlags) => {
|
||||
* @param {StringifyPathDataOptions} options
|
||||
* @returns {string}
|
||||
*/
|
||||
const stringifyPathData = ({ pathData, precision, disableSpaceAfterFlags }) => {
|
||||
export const stringifyPathData = ({
|
||||
pathData,
|
||||
precision,
|
||||
disableSpaceAfterFlags,
|
||||
}) => {
|
||||
if (pathData.length === 1) {
|
||||
const { command, args } = pathData[0];
|
||||
return (
|
||||
@ -377,4 +378,3 @@ const stringifyPathData = ({ pathData, precision, disableSpaceAfterFlags }) => {
|
||||
|
||||
return result;
|
||||
};
|
||||
exports.stringifyPathData = stringifyPathData;
|
||||
|
@ -1,11 +1,9 @@
|
||||
'use strict';
|
||||
import { parsePathData, stringifyPathData } from './path.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types.js').PathDataItem} PathDataItem
|
||||
*/
|
||||
|
||||
const { parsePathData, stringifyPathData } = require('./path.js');
|
||||
|
||||
describe('parse path data', () => {
|
||||
it('should allow spaces between commands', () => {
|
||||
expect(parsePathData('M0 10 L \n\r\t20 30')).toStrictEqual([
|
||||
|
@ -1,28 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types').XastParent} XastParent
|
||||
* @typedef {import('./types').XastRoot} XastRoot
|
||||
* @typedef {import('./types').XastElement} XastElement
|
||||
* @typedef {import('./types').XastInstruction} XastInstruction
|
||||
* @typedef {import('./types').XastDoctype} XastDoctype
|
||||
* @typedef {import('./types').XastText} XastText
|
||||
* @typedef {import('./types').XastCdata} XastCdata
|
||||
* @typedef {import('./types').XastComment} XastComment
|
||||
* @typedef {import('./types').StringifyOptions} StringifyOptions
|
||||
*/
|
||||
|
||||
const { textElems } = require('../plugins/_collections');
|
||||
import { textElems } from '../plugins/_collections.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types.js').XastParent} XastParent
|
||||
* @typedef {import('./types.js').XastRoot} XastRoot
|
||||
* @typedef {import('./types.js').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastInstruction} XastInstruction
|
||||
* @typedef {import('./types.js').XastDoctype} XastDoctype
|
||||
* @typedef {import('./types.js').XastText} XastText
|
||||
* @typedef {import('./types.js').XastCdata} XastCdata
|
||||
* @typedef {import('./types.js').XastComment} XastComment
|
||||
* @typedef {import('./types.js').StringifyOptions} StringifyOptions
|
||||
* @typedef {{
|
||||
* indent: string,
|
||||
* textContext: ?XastElement,
|
||||
* indentLevel: number,
|
||||
* }} State
|
||||
*/
|
||||
|
||||
/**
|
||||
* @typedef {Required<StringifyOptions>} Options
|
||||
*/
|
||||
|
||||
@ -77,7 +69,7 @@ const entities = {
|
||||
*
|
||||
* @type {(data: XastRoot, config: StringifyOptions) => string}
|
||||
*/
|
||||
const stringifySvg = (data, userOptions = {}) => {
|
||||
export const stringifySvg = (data, userOptions = {}) => {
|
||||
/**
|
||||
* @type {Options}
|
||||
*/
|
||||
@ -114,7 +106,6 @@ const stringifySvg = (data, userOptions = {}) => {
|
||||
}
|
||||
return svg;
|
||||
};
|
||||
exports.stringifySvg = stringifySvg;
|
||||
|
||||
/**
|
||||
* @type {(node: XastParent, config: Options, state: State) => string}
|
||||
|
56
lib/style.js
56
lib/style.js
@ -1,29 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('css-tree').Rule} CsstreeRule
|
||||
* @typedef {import('./types').Specificity} Specificity
|
||||
* @typedef {import('./types').Stylesheet} Stylesheet
|
||||
* @typedef {import('./types').StylesheetRule} StylesheetRule
|
||||
* @typedef {import('./types').StylesheetDeclaration} StylesheetDeclaration
|
||||
* @typedef {import('./types').ComputedStyles} ComputedStyles
|
||||
* @typedef {import('./types').XastRoot} XastRoot
|
||||
* @typedef {import('./types').XastElement} XastElement
|
||||
* @typedef {import('./types').XastParent} XastParent
|
||||
* @typedef {import('./types').XastChild} XastChild
|
||||
*/
|
||||
|
||||
const csstree = require('css-tree');
|
||||
const csswhat = require('css-what');
|
||||
const {
|
||||
syntax: { specificity },
|
||||
} = require('csso');
|
||||
const { visit, matches } = require('./xast.js');
|
||||
const {
|
||||
import * as csstree from 'css-tree';
|
||||
import * as csswhat from 'css-what';
|
||||
import { syntax } from 'csso';
|
||||
import { visit, matches } from './xast.js';
|
||||
import {
|
||||
attrsGroups,
|
||||
inheritableAttrs,
|
||||
presentationNonInheritableGroupAttrs,
|
||||
} = require('../plugins/_collections.js');
|
||||
} from '../plugins/_collections.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('css-tree').Rule} CsstreeRule
|
||||
* @typedef {import('./types.js').Specificity} Specificity
|
||||
* @typedef {import('./types.js').Stylesheet} Stylesheet
|
||||
* @typedef {import('./types.js').StylesheetRule} StylesheetRule
|
||||
* @typedef {import('./types.js').StylesheetDeclaration} StylesheetDeclaration
|
||||
* @typedef {import('./types.js').ComputedStyles} ComputedStyles
|
||||
* @typedef {import('./types.js').XastRoot} XastRoot
|
||||
* @typedef {import('./types.js').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastParent} XastParent
|
||||
* @typedef {import('./types.js').XastChild} XastChild
|
||||
*/
|
||||
|
||||
// @ts-ignore not defined in @types/csstree
|
||||
const csstreeWalkSkip = csstree.walk.skip;
|
||||
@ -60,7 +56,7 @@ const parseRule = (ruleNode, dynamic) => {
|
||||
}
|
||||
});
|
||||
rules.push({
|
||||
specificity: specificity(node),
|
||||
specificity: syntax.specificity(node),
|
||||
dynamic: hasPseudoClasses || dynamic,
|
||||
// compute specificity from original node to consider pseudo classes
|
||||
selector: csstree.generate(newNode),
|
||||
@ -201,7 +197,7 @@ const computeOwnStyle = (stylesheet, node) => {
|
||||
* @param {Specificity} b
|
||||
* @returns {number}
|
||||
*/
|
||||
const compareSpecificity = (a, b) => {
|
||||
export const compareSpecificity = (a, b) => {
|
||||
for (let i = 0; i < 4; i += 1) {
|
||||
if (a[i] < b[i]) {
|
||||
return -1;
|
||||
@ -212,12 +208,11 @@ const compareSpecificity = (a, b) => {
|
||||
|
||||
return 0;
|
||||
};
|
||||
exports.compareSpecificity = compareSpecificity;
|
||||
|
||||
/**
|
||||
* @type {(root: XastRoot) => Stylesheet}
|
||||
*/
|
||||
const collectStylesheet = (root) => {
|
||||
export const collectStylesheet = (root) => {
|
||||
/** @type {StylesheetRule[]} */
|
||||
const rules = [];
|
||||
/** @type {Map<XastElement, XastParent>} */
|
||||
@ -253,14 +248,13 @@ const collectStylesheet = (root) => {
|
||||
rules.sort((a, b) => compareSpecificity(a.specificity, b.specificity));
|
||||
return { rules, parents };
|
||||
};
|
||||
exports.collectStylesheet = collectStylesheet;
|
||||
|
||||
/**
|
||||
* @param {Stylesheet} stylesheet
|
||||
* @param {XastElement} node
|
||||
* @returns {ComputedStyles}
|
||||
*/
|
||||
const computeStyle = (stylesheet, node) => {
|
||||
export const computeStyle = (stylesheet, node) => {
|
||||
const { parents } = stylesheet;
|
||||
const computedStyles = computeOwnStyle(stylesheet, node);
|
||||
let parent = parents.get(node);
|
||||
@ -279,7 +273,6 @@ const computeStyle = (stylesheet, node) => {
|
||||
}
|
||||
return computedStyles;
|
||||
};
|
||||
exports.computeStyle = computeStyle;
|
||||
|
||||
/**
|
||||
* Determines if the CSS selector includes or traverses the given attribute.
|
||||
@ -294,7 +287,7 @@ exports.computeStyle = computeStyle;
|
||||
* @param {boolean} traversed
|
||||
* @returns {boolean}
|
||||
*/
|
||||
const includesAttrSelector = (
|
||||
export const includesAttrSelector = (
|
||||
selector,
|
||||
name,
|
||||
value = null,
|
||||
@ -333,4 +326,3 @@ const includesAttrSelector = (
|
||||
|
||||
return false;
|
||||
};
|
||||
exports.includesAttrSelector = includesAttrSelector;
|
||||
|
@ -1,14 +1,12 @@
|
||||
'use strict';
|
||||
import { collectStylesheet, computeStyle } from './style.js';
|
||||
import { visit } from './xast.js';
|
||||
import { parseSvg } from './parser.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types').XastParent} XastParent
|
||||
* @typedef {import('./types').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastParent} XastParent
|
||||
* @typedef {import('./types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
const { collectStylesheet, computeStyle } = require('./style.js');
|
||||
const { visit } = require('./xast.js');
|
||||
const { parseSvg } = require('./parser.js');
|
||||
|
||||
/**
|
||||
* @type {(node: XastParent, id: string) => XastElement}
|
||||
*/
|
||||
|
@ -1,24 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
const os = require('os');
|
||||
const fs = require('fs');
|
||||
const { pathToFileURL } = require('url');
|
||||
const path = require('path');
|
||||
const { optimize: optimizeAgnostic } = require('./svgo.js');
|
||||
import os from 'os';
|
||||
import fs from 'fs';
|
||||
import { pathToFileURL } from 'url';
|
||||
import path from 'path';
|
||||
import { optimize as optimizeAgnostic } from './svgo.js';
|
||||
|
||||
const importConfig = async (configFile) => {
|
||||
let config;
|
||||
// at the moment dynamic import may randomly fail with segfault
|
||||
// to workaround this for some users .cjs extension is loaded
|
||||
// exclusively with require
|
||||
if (configFile.endsWith('.cjs')) {
|
||||
config = require(configFile);
|
||||
} else {
|
||||
// dynamic import expects file url instead of path and may fail
|
||||
// when windows path is provided
|
||||
const { default: imported } = await import(pathToFileURL(configFile));
|
||||
config = imported;
|
||||
}
|
||||
// dynamic import expects file url instead of path and may fail
|
||||
// when windows path is provided
|
||||
const imported = await import(pathToFileURL(configFile));
|
||||
const config = imported.default;
|
||||
|
||||
if (config == null || typeof config !== 'object' || Array.isArray(config)) {
|
||||
throw Error(`Invalid config file "${configFile}"`);
|
||||
}
|
||||
@ -34,7 +25,7 @@ const isFile = async (file) => {
|
||||
}
|
||||
};
|
||||
|
||||
const loadConfig = async (configFile, cwd = process.cwd()) => {
|
||||
export const loadConfig = async (configFile, cwd = process.cwd()) => {
|
||||
if (configFile != null) {
|
||||
if (path.isAbsolute(configFile)) {
|
||||
return await importConfig(configFile);
|
||||
@ -64,9 +55,8 @@ const loadConfig = async (configFile, cwd = process.cwd()) => {
|
||||
dir = parent;
|
||||
}
|
||||
};
|
||||
exports.loadConfig = loadConfig;
|
||||
|
||||
const optimize = (input, config) => {
|
||||
export const optimize = (input, config) => {
|
||||
if (config == null) {
|
||||
config = {};
|
||||
}
|
||||
@ -82,4 +72,3 @@ const optimize = (input, config) => {
|
||||
},
|
||||
});
|
||||
};
|
||||
exports.optimize = optimize;
|
||||
|
@ -1,13 +1,11 @@
|
||||
'use strict';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import { optimize, loadConfig } from './svgo-node.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').Plugin} Plugin
|
||||
* @typedef {import('../lib/types.js').Plugin} Plugin
|
||||
*/
|
||||
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { optimize, loadConfig } = require('./svgo-node.js');
|
||||
|
||||
const describeLF = os.EOL === '\r\n' ? describe.skip : describe;
|
||||
const describeCRLF = os.EOL === '\r\n' ? describe : describe.skip;
|
||||
|
||||
|
6
lib/svgo.d.ts
vendored
6
lib/svgo.d.ts
vendored
@ -1,12 +1,12 @@
|
||||
import type { StringifyOptions, DataUri, Plugin as PluginFn } from './types';
|
||||
import type { StringifyOptions, DataUri, Plugin } from './types.js';
|
||||
import type {
|
||||
BuiltinsWithOptionalParams,
|
||||
BuiltinsWithRequiredParams,
|
||||
} from '../plugins/plugins-types';
|
||||
} from '../plugins/plugins-types.js';
|
||||
|
||||
type CustomPlugin = {
|
||||
name: string;
|
||||
fn: PluginFn<void>;
|
||||
fn: Plugin<void>;
|
||||
};
|
||||
|
||||
type PluginConfig =
|
||||
|
15
lib/svgo.js
15
lib/svgo.js
@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
|
||||
const { parseSvg } = require('./parser.js');
|
||||
const { stringifySvg } = require('./stringifier.js');
|
||||
const { builtin } = require('./builtin.js');
|
||||
const { invokePlugins } = require('./svgo/plugins.js');
|
||||
const { encodeSVGDatauri } = require('./svgo/tools.js');
|
||||
import { parseSvg } from './parser.js';
|
||||
import { stringifySvg } from './stringifier.js';
|
||||
import { builtin } from './builtin.js';
|
||||
import { invokePlugins } from './svgo/plugins.js';
|
||||
import { encodeSVGDatauri } from './svgo/tools.js';
|
||||
|
||||
const pluginsMap = {};
|
||||
for (const plugin of builtin) {
|
||||
@ -47,7 +45,7 @@ const resolvePluginConfig = (plugin) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
const optimize = (input, config) => {
|
||||
export const optimize = (input, config) => {
|
||||
if (config == null) {
|
||||
config = {};
|
||||
}
|
||||
@ -99,4 +97,3 @@ const optimize = (input, config) => {
|
||||
data: output,
|
||||
};
|
||||
};
|
||||
exports.optimize = optimize;
|
||||
|
@ -1,11 +1,10 @@
|
||||
'use strict';
|
||||
import { jest } from '@jest/globals';
|
||||
import { optimize } from './svgo.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').Plugin} Plugin
|
||||
* @typedef {import('../lib/types.js').Plugin} Plugin
|
||||
*/
|
||||
|
||||
const { optimize } = require('./svgo.js');
|
||||
|
||||
test('allow to setup default preset', () => {
|
||||
const svg = `
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
@ -1,12 +1,14 @@
|
||||
'use strict';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import colors from 'picocolors';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { encodeSVGDatauri, decodeSVGDatauri } from './tools.js';
|
||||
import { loadConfig, optimize } from '../svgo-node.js';
|
||||
import { builtin } from '../builtin.js';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const colors = require('picocolors');
|
||||
const { loadConfig, optimize } = require('../svgo-node.js');
|
||||
const { builtin } = require('../builtin.js');
|
||||
const PKG = require('../../package.json');
|
||||
const { encodeSVGDatauri, decodeSVGDatauri } = require('./tools.js');
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const pkgPath = path.join(__dirname, '../../package.json');
|
||||
const PKG = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
||||
|
||||
const regSVGFile = /\.svg$/i;
|
||||
|
||||
@ -15,7 +17,7 @@ const regSVGFile = /\.svg$/i;
|
||||
*
|
||||
* @param {string} path
|
||||
*/
|
||||
function checkIsDir(path) {
|
||||
export function checkIsDir(path) {
|
||||
try {
|
||||
return fs.lstatSync(path).isDirectory();
|
||||
} catch (e) {
|
||||
@ -23,7 +25,7 @@ function checkIsDir(path) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = function makeProgram(program) {
|
||||
export default function makeProgram(program) {
|
||||
program
|
||||
.name(PKG.name)
|
||||
.description(PKG.description, {
|
||||
@ -77,7 +79,7 @@ module.exports = function makeProgram(program) {
|
||||
// used by picocolors internally
|
||||
.option('--no-color', 'Output plain text without color')
|
||||
.action(action);
|
||||
};
|
||||
}
|
||||
|
||||
async function action(args, opts, command) {
|
||||
var input = opts.input || args;
|
||||
@ -524,5 +526,3 @@ function showAvailablePlugins() {
|
||||
.join('\n');
|
||||
console.log('Currently available plugins:\n' + list);
|
||||
}
|
||||
|
||||
module.exports.checkIsDir = checkIsDir;
|
||||
|
2
lib/svgo/css-select-adapter.d.ts
vendored
2
lib/svgo/css-select-adapter.d.ts
vendored
@ -1,2 +1,2 @@
|
||||
declare let obj: any;
|
||||
export = obj;
|
||||
export default obj;
|
||||
|
@ -1,5 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
const isTag = (node) => {
|
||||
return node.type === 'element';
|
||||
};
|
||||
@ -117,4 +115,4 @@ const svgoCssSelectAdapter = {
|
||||
findOne,
|
||||
};
|
||||
|
||||
module.exports = svgoCssSelectAdapter;
|
||||
export default svgoCssSelectAdapter;
|
||||
|
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const { visit } = require('../xast.js');
|
||||
import { visit } from '../xast.js';
|
||||
|
||||
/**
|
||||
* Plugins engine.
|
||||
@ -12,7 +10,13 @@ const { visit } = require('../xast.js');
|
||||
* @param {Array} plugins plugins object from config
|
||||
* @return {Object} output ast
|
||||
*/
|
||||
const invokePlugins = (ast, info, plugins, overrides, globalOverrides) => {
|
||||
export const invokePlugins = (
|
||||
ast,
|
||||
info,
|
||||
plugins,
|
||||
overrides,
|
||||
globalOverrides,
|
||||
) => {
|
||||
for (const plugin of plugins) {
|
||||
const override = overrides?.[plugin.name];
|
||||
if (override === false) {
|
||||
@ -26,9 +30,8 @@ const invokePlugins = (ast, info, plugins, overrides, globalOverrides) => {
|
||||
}
|
||||
}
|
||||
};
|
||||
exports.invokePlugins = invokePlugins;
|
||||
|
||||
const createPreset = ({ name, plugins }) => {
|
||||
export const createPreset = ({ name, plugins }) => {
|
||||
return {
|
||||
name,
|
||||
fn: (ast, params, info) => {
|
||||
@ -58,4 +61,3 @@ const createPreset = ({ name, plugins }) => {
|
||||
},
|
||||
};
|
||||
};
|
||||
exports.createPreset = createPreset;
|
||||
|
@ -1,12 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../types').PathDataCommand} PathDataCommand
|
||||
* @typedef {import('../types').DataUri} DataUri
|
||||
* @typedef {import('../types.js').DataUri} DataUri
|
||||
* @typedef {import('../types.js').PathDataCommand} PathDataCommand
|
||||
* @typedef {import('../../lib/types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
const { attrsGroups, referencesProps } = require('../../plugins/_collections');
|
||||
import { attrsGroups, referencesProps } from '../../plugins/_collections.js';
|
||||
|
||||
const regReferencesUrl = /\burl\((["'])?#(.+?)\1\)/g;
|
||||
const regReferencesHref = /^#(.+?)$/;
|
||||
@ -17,7 +15,7 @@ const regReferencesBegin = /(\w+)\.[a-zA-Z]/;
|
||||
*
|
||||
* @type {(str: string, type?: DataUri) => string}
|
||||
*/
|
||||
exports.encodeSVGDatauri = (str, type) => {
|
||||
export const encodeSVGDatauri = (str, type) => {
|
||||
var prefix = 'data:image/svg+xml';
|
||||
if (!type || type === 'base64') {
|
||||
// base64
|
||||
@ -38,7 +36,7 @@ exports.encodeSVGDatauri = (str, type) => {
|
||||
*
|
||||
* @type {(str: string) => string}
|
||||
*/
|
||||
exports.decodeSVGDatauri = (str) => {
|
||||
export const decodeSVGDatauri = (str) => {
|
||||
var regexp = /data:image\/svg\+xml(;charset=[^;,]*)?(;base64)?,(.*)/;
|
||||
var match = regexp.exec(str);
|
||||
|
||||
@ -76,7 +74,7 @@ exports.decodeSVGDatauri = (str) => {
|
||||
*
|
||||
* @type {(data: number[], params: CleanupOutDataParams, command?: PathDataCommand) => string}
|
||||
*/
|
||||
exports.cleanupOutData = (data, params, command) => {
|
||||
export const cleanupOutData = (data, params, command) => {
|
||||
let str = '';
|
||||
let delimiter;
|
||||
/**
|
||||
@ -130,7 +128,7 @@ exports.cleanupOutData = (data, params, command) => {
|
||||
* 0.5 → .5
|
||||
* -0.5 → -.5
|
||||
*/
|
||||
const removeLeadingZero = (value) => {
|
||||
export const removeLeadingZero = (value) => {
|
||||
const strValue = value.toString();
|
||||
|
||||
if (0 < value && value < 1 && strValue.startsWith('0')) {
|
||||
@ -143,7 +141,6 @@ const removeLeadingZero = (value) => {
|
||||
|
||||
return strValue;
|
||||
};
|
||||
exports.removeLeadingZero = removeLeadingZero;
|
||||
|
||||
/**
|
||||
* If the current node contains any scripts. This does not check parents or
|
||||
@ -152,7 +149,7 @@ exports.removeLeadingZero = removeLeadingZero;
|
||||
* @param {XastElement} node Current node to check against.
|
||||
* @returns {boolean} If the current node contains scripts.
|
||||
*/
|
||||
const hasScripts = (node) => {
|
||||
export const hasScripts = (node) => {
|
||||
if (node.name === 'script' && node.children.length !== 0) {
|
||||
return true;
|
||||
}
|
||||
@ -180,7 +177,6 @@ const hasScripts = (node) => {
|
||||
|
||||
return eventAttrs.some((attr) => node.attributes[attr] != null);
|
||||
};
|
||||
exports.hasScripts = hasScripts;
|
||||
|
||||
/**
|
||||
* For example, a string that contains one or more of following would match and
|
||||
@ -192,17 +188,16 @@ exports.hasScripts = hasScripts;
|
||||
* @param {string} body
|
||||
* @returns {boolean} If the given string includes a URL reference.
|
||||
*/
|
||||
const includesUrlReference = (body) => {
|
||||
export const includesUrlReference = (body) => {
|
||||
return new RegExp(regReferencesUrl).test(body);
|
||||
};
|
||||
exports.includesUrlReference = includesUrlReference;
|
||||
|
||||
/**
|
||||
* @param {string} attribute
|
||||
* @param {string} value
|
||||
* @returns {string[]}
|
||||
*/
|
||||
const findReferences = (attribute, value) => {
|
||||
export const findReferences = (attribute, value) => {
|
||||
const results = [];
|
||||
|
||||
if (referencesProps.has(attribute)) {
|
||||
@ -228,7 +223,6 @@ const findReferences = (attribute, value) => {
|
||||
|
||||
return results.map((body) => decodeURI(body));
|
||||
};
|
||||
exports.findReferences = findReferences;
|
||||
|
||||
/**
|
||||
* Does the same as {@link Number.toFixed} but without casting
|
||||
@ -238,8 +232,7 @@ exports.findReferences = findReferences;
|
||||
* @param {number} precision
|
||||
* @returns {number}
|
||||
*/
|
||||
const toFixed = (num, precision) => {
|
||||
export const toFixed = (num, precision) => {
|
||||
const pow = 10 ** precision;
|
||||
return Math.round(num * pow) / pow;
|
||||
};
|
||||
exports.toFixed = toFixed;
|
||||
|
32
lib/xast.js
32
lib/xast.js
@ -1,15 +1,13 @@
|
||||
'use strict';
|
||||
import { selectAll, selectOne, is } from 'css-select';
|
||||
import xastAdaptor from './svgo/css-select-adapter.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types').XastNode} XastNode
|
||||
* @typedef {import('./types').XastChild} XastChild
|
||||
* @typedef {import('./types').XastParent} XastParent
|
||||
* @typedef {import('./types').Visitor} Visitor
|
||||
* @typedef {import('./types.js').XastNode} XastNode
|
||||
* @typedef {import('./types.js').XastChild} XastChild
|
||||
* @typedef {import('./types.js').XastParent} XastParent
|
||||
* @typedef {import('./types.js').Visitor} Visitor
|
||||
*/
|
||||
|
||||
const { selectAll, selectOne, is } = require('css-select');
|
||||
const xastAdaptor = require('./svgo/css-select-adapter.js');
|
||||
|
||||
const cssSelectOptions = {
|
||||
xmlMode: true,
|
||||
adapter: xastAdaptor,
|
||||
@ -18,34 +16,30 @@ const cssSelectOptions = {
|
||||
/**
|
||||
* @type {(node: XastNode, selector: string) => XastChild[]}
|
||||
*/
|
||||
const querySelectorAll = (node, selector) => {
|
||||
export const querySelectorAll = (node, selector) => {
|
||||
return selectAll(selector, node, cssSelectOptions);
|
||||
};
|
||||
exports.querySelectorAll = querySelectorAll;
|
||||
|
||||
/**
|
||||
* @type {(node: XastNode, selector: string) => ?XastChild}
|
||||
*/
|
||||
const querySelector = (node, selector) => {
|
||||
export const querySelector = (node, selector) => {
|
||||
return selectOne(selector, node, cssSelectOptions);
|
||||
};
|
||||
exports.querySelector = querySelector;
|
||||
|
||||
/**
|
||||
* @type {(node: XastChild, selector: string) => boolean}
|
||||
*/
|
||||
const matches = (node, selector) => {
|
||||
export const matches = (node, selector) => {
|
||||
return is(node, selector, cssSelectOptions);
|
||||
};
|
||||
exports.matches = matches;
|
||||
|
||||
const visitSkip = Symbol();
|
||||
exports.visitSkip = visitSkip;
|
||||
export const visitSkip = Symbol();
|
||||
|
||||
/**
|
||||
* @type {(node: XastNode, visitor: Visitor, parentNode?: any) => void}
|
||||
*/
|
||||
const visit = (node, visitor, parentNode) => {
|
||||
export const visit = (node, visitor, parentNode) => {
|
||||
const callbacks = visitor[node.type];
|
||||
if (callbacks && callbacks.enter) {
|
||||
// @ts-ignore hard to infer
|
||||
@ -74,14 +68,12 @@ const visit = (node, visitor, parentNode) => {
|
||||
callbacks.exit(node, parentNode);
|
||||
}
|
||||
};
|
||||
exports.visit = visit;
|
||||
|
||||
/**
|
||||
* @param {XastChild} node
|
||||
* @param {XastParent} parentNode
|
||||
*/
|
||||
const detachNodeFromParent = (node, parentNode) => {
|
||||
export const detachNodeFromParent = (node, parentNode) => {
|
||||
// avoid splice to not break for loops
|
||||
parentNode.children = parentNode.children.filter((child) => child !== node);
|
||||
};
|
||||
exports.detachNodeFromParent = detachNodeFromParent;
|
||||
|
@ -1,11 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('./types').XastRoot} XastRoot
|
||||
* @typedef {import('./types').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastElement} XastElement
|
||||
* @typedef {import('./types.js').XastRoot} XastRoot
|
||||
*/
|
||||
|
||||
const { visit, visitSkip, detachNodeFromParent } = require('./xast.js');
|
||||
import { visit, visitSkip, detachNodeFromParent } from './xast.js';
|
||||
|
||||
/**
|
||||
* @type {(children: XastElement[]) => XastRoot}
|
||||
|
24
package.json
24
package.json
@ -1,9 +1,10 @@
|
||||
{
|
||||
"packageManager": "yarn@2.4.3",
|
||||
"name": "svgo",
|
||||
"version": "3.2.0",
|
||||
"version": "3.3.0",
|
||||
"description": "Nodejs-based tool for optimizing SVG vector graphics files",
|
||||
"license": "MIT",
|
||||
"type": "module",
|
||||
"keywords": [
|
||||
"svgo",
|
||||
"svg",
|
||||
@ -50,8 +51,12 @@
|
||||
"url": "https://opencollective.com/svgo"
|
||||
},
|
||||
"main": "./lib/svgo-node.js",
|
||||
"bin": "./bin/svgo",
|
||||
"bin": "./bin/svgo.js",
|
||||
"types": "./lib/svgo.d.ts",
|
||||
"exports": {
|
||||
"require": "./dist/svgo-node.cjs",
|
||||
"default": "./lib/svgo-node.js"
|
||||
},
|
||||
"files": [
|
||||
"bin",
|
||||
"lib",
|
||||
@ -67,10 +72,11 @@
|
||||
"lint": "eslint --ignore-path .gitignore . && prettier --check . --ignore-path .gitignore",
|
||||
"fix": "eslint --ignore-path .gitignore --fix . && prettier --write . --ignore-path .gitignore",
|
||||
"typecheck": "tsc",
|
||||
"test-browser": "rollup -c && node ./test/browser.js",
|
||||
"generate-bundles": "rollup -c",
|
||||
"test-bundles": "yarn generate-bundles && node ./test/svgo.cjs && node ./test/browser.js",
|
||||
"test-regression": "node ./test/regression-extract.js && NO_DIFF=1 node ./test/regression.js",
|
||||
"prepublishOnly": "rm -rf dist && rollup -c",
|
||||
"qa": "yarn lint && yarn typecheck && yarn test && yarn test-browser && yarn test-regression"
|
||||
"prepublishOnly": "rm -rf dist && yarn generate-bundles",
|
||||
"qa": "yarn lint && yarn typecheck && yarn test && yarn test-bundles && yarn test-regression"
|
||||
},
|
||||
"jest": {
|
||||
"coveragePathIgnorePatterns": [
|
||||
@ -87,8 +93,9 @@
|
||||
"picocolors": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-commonjs": "^22.0.2",
|
||||
"@rollup/plugin-node-resolve": "^14.1.0",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@rollup/plugin-terser": "^0.4.4",
|
||||
"@types/css-tree": "^2.3.4",
|
||||
"@types/csso": "^5.0.4",
|
||||
"@types/jest": "^29.5.5",
|
||||
@ -100,8 +107,7 @@
|
||||
"playwright": "^1.40.1",
|
||||
"pngjs": "^7.0.0",
|
||||
"prettier": "^3.1.1",
|
||||
"rollup": "^2.79.1",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup": "^4.9.2",
|
||||
"tar-stream": "^3.1.6",
|
||||
"typescript": "^5.3.3"
|
||||
}
|
||||
|
@ -1,11 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
// https://www.w3.org/TR/SVG11/intro.html#Definitions
|
||||
|
||||
/**
|
||||
* @type {Record<string, Set<string>>}
|
||||
*/
|
||||
exports.elemsGroups = {
|
||||
export const elemsGroups = {
|
||||
animation: new Set([
|
||||
'animate',
|
||||
'animateColor',
|
||||
@ -107,19 +105,15 @@ exports.elemsGroups = {
|
||||
*
|
||||
* @see https://developer.mozilla.org/docs/Web/HTML/Element/pre
|
||||
*/
|
||||
exports.textElems = new Set([
|
||||
...exports.elemsGroups.textContent,
|
||||
'pre',
|
||||
'title',
|
||||
]);
|
||||
export const textElems = new Set([...elemsGroups.textContent, 'pre', 'title']);
|
||||
|
||||
exports.pathElems = new Set(['glyph', 'missing-glyph', 'path']);
|
||||
export const pathElems = new Set(['glyph', 'missing-glyph', 'path']);
|
||||
|
||||
/**
|
||||
* @type {Record<string, Set<string>>}
|
||||
* @see https://www.w3.org/TR/SVG11/intro.html#Definitions
|
||||
*/
|
||||
exports.attrsGroups = {
|
||||
export const attrsGroups = {
|
||||
animationAddition: new Set(['additive', 'accumulate']),
|
||||
animationAttributeTarget: new Set(['attributeType', 'attributeName']),
|
||||
animationEvent: new Set(['onbegin', 'onend', 'onrepeat', 'onload']),
|
||||
@ -317,7 +311,7 @@ exports.attrsGroups = {
|
||||
/**
|
||||
* @type {Record<string, Record<string, string>>}
|
||||
*/
|
||||
exports.attrsGroupsDefaults = {
|
||||
export const attrsGroupsDefaults = {
|
||||
core: { 'xml:space': 'default' },
|
||||
presentation: {
|
||||
clip: 'auto',
|
||||
@ -391,7 +385,7 @@ exports.attrsGroupsDefaults = {
|
||||
* }>}
|
||||
* @see https://www.w3.org/TR/SVG11/eltindex.html
|
||||
*/
|
||||
exports.elems = {
|
||||
export const elems = {
|
||||
a: {
|
||||
attrsGroups: new Set([
|
||||
'conditionalProcessing',
|
||||
@ -1971,7 +1965,7 @@ exports.elems = {
|
||||
};
|
||||
|
||||
// https://wiki.inkscape.org/wiki/index.php/Inkscape-specific_XML_attributes
|
||||
exports.editorNamespaces = new Set([
|
||||
export const editorNamespaces = new Set([
|
||||
'http://creativecommons.org/ns#',
|
||||
'http://inkscape.sourceforge.net/DTD/sodipodi-0.dtd',
|
||||
'http://ns.adobe.com/AdobeIllustrator/10.0/',
|
||||
@ -1999,7 +1993,7 @@ exports.editorNamespaces = new Set([
|
||||
/**
|
||||
* @see https://www.w3.org/TR/SVG11/linking.html#processingIRI
|
||||
*/
|
||||
exports.referencesProps = new Set([
|
||||
export const referencesProps = new Set([
|
||||
'clip-path',
|
||||
'color-profile',
|
||||
'fill',
|
||||
@ -2015,7 +2009,7 @@ exports.referencesProps = new Set([
|
||||
/**
|
||||
* @see https://www.w3.org/TR/SVG11/propidx.html
|
||||
*/
|
||||
exports.inheritableAttrs = new Set([
|
||||
export const inheritableAttrs = new Set([
|
||||
'clip-rule',
|
||||
'color-interpolation-filters',
|
||||
'color-interpolation',
|
||||
@ -2063,7 +2057,7 @@ exports.inheritableAttrs = new Set([
|
||||
'writing-mode',
|
||||
]);
|
||||
|
||||
exports.presentationNonInheritableGroupAttrs = new Set([
|
||||
export const presentationNonInheritableGroupAttrs = new Set([
|
||||
'clip-path',
|
||||
'display',
|
||||
'filter',
|
||||
@ -2079,7 +2073,7 @@ exports.presentationNonInheritableGroupAttrs = new Set([
|
||||
*
|
||||
* @type {Record<string, string>}
|
||||
*/
|
||||
exports.colorsNames = {
|
||||
export const colorsNames = {
|
||||
aliceblue: '#f0f8ff',
|
||||
antiquewhite: '#faebd7',
|
||||
aqua: '#0ff',
|
||||
@ -2233,7 +2227,7 @@ exports.colorsNames = {
|
||||
/**
|
||||
* @type {Record<string, string>}
|
||||
*/
|
||||
exports.colorsShortNames = {
|
||||
export const colorsShortNames = {
|
||||
'#f0ffff': 'azure',
|
||||
'#f5f5dc': 'beige',
|
||||
'#ffe4c4': 'bisque',
|
||||
@ -2271,7 +2265,7 @@ exports.colorsShortNames = {
|
||||
/**
|
||||
* @see https://www.w3.org/TR/SVG11/single-page.html#types-DataTypeColor
|
||||
*/
|
||||
exports.colorsProps = new Set([
|
||||
export const colorsProps = new Set([
|
||||
'color',
|
||||
'fill',
|
||||
'flood-color',
|
||||
@ -2281,7 +2275,7 @@ exports.colorsProps = new Set([
|
||||
]);
|
||||
|
||||
/** @see https://developer.mozilla.org/docs/Web/CSS/Pseudo-classes */
|
||||
exports.pseudoClasses = {
|
||||
export const pseudoClasses = {
|
||||
displayState: new Set(['fullscreen', 'modal', 'picture-in-picture']),
|
||||
input: new Set([
|
||||
'autofill',
|
||||
|
@ -1,12 +1,10 @@
|
||||
'use strict';
|
||||
import { parsePathData, stringifyPathData } from '../lib/path.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').PathDataItem} PathDataItem
|
||||
*/
|
||||
|
||||
const { parsePathData, stringifyPathData } = require('../lib/path.js');
|
||||
|
||||
/**
|
||||
* @type {[number, number]}
|
||||
*/
|
||||
@ -17,7 +15,7 @@ var prevCtrlPoint;
|
||||
*
|
||||
* @type {(path: XastElement) => PathDataItem[]}
|
||||
*/
|
||||
const path2js = (path) => {
|
||||
export const path2js = (path) => {
|
||||
// @ts-ignore legacy
|
||||
if (path.pathJS) return path.pathJS;
|
||||
/**
|
||||
@ -36,7 +34,6 @@ const path2js = (path) => {
|
||||
path.pathJS = pathData;
|
||||
return pathData;
|
||||
};
|
||||
exports.path2js = path2js;
|
||||
|
||||
/**
|
||||
* Convert relative Path data to absolute.
|
||||
@ -181,7 +178,7 @@ const convertRelativeToAbsolute = (data) => {
|
||||
*
|
||||
* @type {(path: XastElement, data: PathDataItem[], params: Js2PathParams) => void}
|
||||
*/
|
||||
exports.js2path = function (path, data, params) {
|
||||
export const js2path = function (path, data, params) {
|
||||
// @ts-ignore legacy
|
||||
path.pathJS = data;
|
||||
|
||||
@ -226,7 +223,7 @@ function set(dest, source) {
|
||||
*
|
||||
* @type {(path1: PathDataItem[], path2: PathDataItem[]) => boolean}
|
||||
*/
|
||||
exports.intersects = function (path1, path2) {
|
||||
export const intersects = function (path1, path2) {
|
||||
// Collect points of every subpath.
|
||||
const points1 = gatherPoints(convertRelativeToAbsolute(path1));
|
||||
const points2 = gatherPoints(convertRelativeToAbsolute(path2));
|
||||
|
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const { toFixed } = require('../lib/svgo/tools');
|
||||
import { toFixed } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {{ name: string, data: number[] }} TransformItem
|
||||
@ -38,7 +36,7 @@ const regNumericValues = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
|
||||
* @param {string} transformString
|
||||
* @returns {TransformItem[]} Object representation of transform, or an empty array if it was malformed.
|
||||
*/
|
||||
exports.transform2js = (transformString) => {
|
||||
export const transform2js = (transformString) => {
|
||||
/** @type {TransformItem[]} */
|
||||
const transforms = [];
|
||||
/** @type {?TransformItem} */
|
||||
@ -69,14 +67,13 @@ exports.transform2js = (transformString) => {
|
||||
? []
|
||||
: transforms;
|
||||
};
|
||||
|
||||
/**
|
||||
* Multiply transforms into one.
|
||||
*
|
||||
* @param {TransformItem[]} transforms
|
||||
* @returns {TransformItem}
|
||||
*/
|
||||
exports.transformsMultiply = (transforms) => {
|
||||
export const transformsMultiply = (transforms) => {
|
||||
const matrixData = transforms.map((transform) => {
|
||||
if (transform.name === 'matrix') {
|
||||
return transform.data;
|
||||
@ -173,7 +170,7 @@ const mth = {
|
||||
* @returns {TransformItem[]}
|
||||
* @see https://frederic-wang.fr/decomposition-of-2d-transform-matrices.html
|
||||
*/
|
||||
exports.matrixToTransform = (transform, params) => {
|
||||
export const matrixToTransform = (transform, params) => {
|
||||
const floatPrecision = params.floatPrecision;
|
||||
const data = transform.data;
|
||||
const transforms = [];
|
||||
@ -337,7 +334,7 @@ const transformToMatrix = (transform) => {
|
||||
* transform: number[]
|
||||
* ) => number[]}
|
||||
*/
|
||||
exports.transformArc = (cursor, arc, transform) => {
|
||||
export const transformArc = (cursor, arc, transform) => {
|
||||
const x = arc[5] - cursor[0];
|
||||
const y = arc[6] - cursor[1];
|
||||
let a = arc[0];
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'addAttributesToSVGElement';
|
||||
exports.description = 'adds attributes to an outer <svg> element';
|
||||
export const name = 'addAttributesToSVGElement';
|
||||
export const description = 'adds attributes to an outer <svg> element';
|
||||
|
||||
var ENOCLS = `Error in plugin "addAttributesToSVGElement": absent parameters.
|
||||
It should have a list of "attributes" or one "attribute".
|
||||
@ -47,9 +45,9 @@ plugins: [
|
||||
*
|
||||
* @author April Arcus
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'addAttributesToSVGElement'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'addAttributesToSVGElement'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
if (!Array.isArray(params.attributes) && !params.attribute) {
|
||||
console.error(ENOCLS);
|
||||
return null;
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'addClassesToSVGElement';
|
||||
exports.description = 'adds classnames to an outer <svg> element';
|
||||
export const name = 'addClassesToSVGElement';
|
||||
export const description = 'adds classnames to an outer <svg> element';
|
||||
|
||||
var ENOCLS = `Error in plugin "addClassesToSVGElement": absent parameters.
|
||||
It should have a list of classes in "classNames" or one "className".
|
||||
@ -49,9 +47,9 @@ plugins: [
|
||||
*
|
||||
* @author April Arcus
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'addClassesToSVGElement'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'addClassesToSVGElement'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
if (
|
||||
!(Array.isArray(params.classNames) && params.classNames.some(String)) &&
|
||||
!params.className
|
||||
|
@ -1,22 +1,18 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const {
|
||||
import { path2js } from './_path.js';
|
||||
import {
|
||||
transformsMultiply,
|
||||
transform2js,
|
||||
transformArc,
|
||||
} = require('./_transforms.js');
|
||||
const { path2js } = require('./_path.js');
|
||||
const {
|
||||
removeLeadingZero,
|
||||
includesUrlReference,
|
||||
} = require('../lib/svgo/tools.js');
|
||||
const { referencesProps, attrsGroupsDefaults } = require('./_collections.js');
|
||||
} from './_transforms.js';
|
||||
import { referencesProps, attrsGroupsDefaults } from './_collections.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
|
||||
import { removeLeadingZero, includesUrlReference } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {PathDataItem[]} PathData
|
||||
@ -28,12 +24,12 @@ const regNumericValues = /[-+]?(\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
|
||||
/**
|
||||
* Apply transformation(s) to the Path data.
|
||||
*
|
||||
* @type {import('../lib/types').Plugin<{
|
||||
* @type {import('../lib/types.js').Plugin<{
|
||||
* transformPrecision: number,
|
||||
* applyTransformsStroked: boolean,
|
||||
* }>}
|
||||
*/
|
||||
const applyTransforms = (root, params) => {
|
||||
export const applyTransforms = (root, params) => {
|
||||
const stylesheet = collectStylesheet(root);
|
||||
return {
|
||||
element: {
|
||||
@ -160,7 +156,6 @@ const applyTransforms = (root, params) => {
|
||||
},
|
||||
};
|
||||
};
|
||||
exports.applyTransforms = applyTransforms;
|
||||
|
||||
/**
|
||||
* @type {(matrix: Matrix, x: number, y: number) => [number, number]}
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'cleanupAttrs';
|
||||
exports.description =
|
||||
export const name = 'cleanupAttrs';
|
||||
export const description =
|
||||
'cleanups attributes from newlines, trailing and repeating spaces';
|
||||
|
||||
const regNewlinesNeedSpace = /(\S)\r?\n(\S)/g;
|
||||
@ -12,10 +10,9 @@ const regSpaces = /\s{2,}/g;
|
||||
* Cleanup attributes values from newlines, trailing and repeating spaces.
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'cleanupAttrs'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'cleanupAttrs'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const { newlines = true, trim = true, spaces = true } = params;
|
||||
return {
|
||||
element: {
|
||||
|
@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
import * as csstree from 'css-tree';
|
||||
import { visit } from '../lib/xast.js';
|
||||
|
||||
const csstree = require('css-tree');
|
||||
const { visit } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'cleanupEnableBackground';
|
||||
exports.description =
|
||||
export const name = 'cleanupEnableBackground';
|
||||
export const description =
|
||||
'remove or cleanup enable-background attribute when possible';
|
||||
|
||||
const regEnableBackground =
|
||||
@ -19,9 +17,9 @@ const regEnableBackground =
|
||||
* ⬇
|
||||
* <svg width="100" height="50">
|
||||
* @author Kir Belevich
|
||||
* @type {import('./plugins-types').Plugin<'cleanupEnableBackground'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'cleanupEnableBackground'>}
|
||||
*/
|
||||
exports.fn = (root) => {
|
||||
export const fn = (root) => {
|
||||
let hasFilter = false;
|
||||
|
||||
visit(root, {
|
||||
|
@ -1,14 +1,12 @@
|
||||
'use strict';
|
||||
import { visitSkip } from '../lib/xast.js';
|
||||
import { hasScripts, findReferences } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
const { visitSkip } = require('../lib/xast.js');
|
||||
const { hasScripts, findReferences } = require('../lib/svgo/tools');
|
||||
|
||||
exports.name = 'cleanupIds';
|
||||
exports.description = 'removes unused IDs and minifies used';
|
||||
export const name = 'cleanupIds';
|
||||
export const description = 'removes unused IDs and minifies used';
|
||||
|
||||
const generateIdChars = [
|
||||
'a',
|
||||
@ -121,9 +119,9 @@ const getIdString = (arr) => {
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'cleanupIds'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'cleanupIds'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const {
|
||||
remove = true,
|
||||
minify = true,
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { removeLeadingZero } from '../lib/svgo/tools.js';
|
||||
|
||||
const { removeLeadingZero } = require('../lib/svgo/tools.js');
|
||||
|
||||
exports.name = 'cleanupListOfValues';
|
||||
exports.description = 'rounds list of values to the fixed precision';
|
||||
export const name = 'cleanupListOfValues';
|
||||
export const description = 'rounds list of values to the fixed precision';
|
||||
|
||||
const regNumericValues =
|
||||
/^([-+]?\d*\.?\d+([eE][-+]?\d+)?)(px|pt|pc|mm|cm|m|in|ft|em|ex|%)?$/;
|
||||
@ -32,9 +30,9 @@ const absoluteLengths = {
|
||||
*
|
||||
* @author kiyopikko
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'cleanupListOfValues'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'cleanupListOfValues'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const {
|
||||
floatPrecision = 3,
|
||||
leadingZero = true,
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { removeLeadingZero } from '../lib/svgo/tools.js';
|
||||
|
||||
const { removeLeadingZero } = require('../lib/svgo/tools');
|
||||
|
||||
exports.name = 'cleanupNumericValues';
|
||||
exports.description =
|
||||
export const name = 'cleanupNumericValues';
|
||||
export const description =
|
||||
'rounds numeric values to the fixed precision, removes default ‘px’ units';
|
||||
|
||||
const regNumericValues =
|
||||
@ -25,9 +23,9 @@ const absoluteLengths = {
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'cleanupNumericValues'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'cleanupNumericValues'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const {
|
||||
floatPrecision = 3,
|
||||
leadingZero = true,
|
||||
|
@ -1,13 +1,11 @@
|
||||
'use strict';
|
||||
import { inheritableAttrs, elemsGroups } from './_collections.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastNode} XastNode
|
||||
* @typedef {import('../lib/types.js').XastNode} XastNode
|
||||
*/
|
||||
|
||||
const { inheritableAttrs, elemsGroups } = require('./_collections.js');
|
||||
|
||||
exports.name = 'collapseGroups';
|
||||
exports.description = 'collapses useless groups';
|
||||
export const name = 'collapseGroups';
|
||||
export const description = 'collapses useless groups';
|
||||
|
||||
/**
|
||||
* @type {(node: XastNode, name: string) => boolean}
|
||||
@ -49,9 +47,9 @@ const hasAnimatedAttr = (node, name) => {
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'collapseGroups'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'collapseGroups'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
exit: (node, parentNode) => {
|
||||
|
@ -1,9 +1,8 @@
|
||||
'use strict';
|
||||
import { colorsNames, colorsProps, colorsShortNames } from './_collections.js';
|
||||
|
||||
const collections = require('./_collections.js');
|
||||
|
||||
exports.name = 'convertColors';
|
||||
exports.description = 'converts colors: rgb() to #rrggbb and #rrggbb to #rgb';
|
||||
export const name = 'convertColors';
|
||||
export const description =
|
||||
'converts colors: rgb() to #rrggbb and #rrggbb to #rgb';
|
||||
|
||||
const rNumber = '([+-]?(?:\\d*\\.\\d+|\\d+\\.?)%?)';
|
||||
const rComma = '\\s*,\\s*';
|
||||
@ -61,9 +60,9 @@ const convertRgbToHex = ([r, g, b]) => {
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'convertColors'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'convertColors'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const {
|
||||
currentColor = false,
|
||||
names2hex = true,
|
||||
@ -76,7 +75,7 @@ exports.fn = (_root, params) => {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
for (const [name, value] of Object.entries(node.attributes)) {
|
||||
if (collections.colorsProps.has(name)) {
|
||||
if (colorsProps.has(name)) {
|
||||
let val = value;
|
||||
|
||||
// convert colors to currentColor
|
||||
@ -97,8 +96,8 @@ exports.fn = (_root, params) => {
|
||||
// convert color name keyword to long hex
|
||||
if (names2hex) {
|
||||
const colorName = val.toLowerCase();
|
||||
if (collections.colorsNames[colorName] != null) {
|
||||
val = collections.colorsNames[colorName];
|
||||
if (colorsNames[colorName] != null) {
|
||||
val = colorsNames[colorName];
|
||||
}
|
||||
}
|
||||
|
||||
@ -130,8 +129,8 @@ exports.fn = (_root, params) => {
|
||||
// convert hex to short name
|
||||
if (shortname) {
|
||||
const colorName = val.toLowerCase();
|
||||
if (collections.colorsShortNames[colorName] != null) {
|
||||
val = collections.colorsShortNames[colorName];
|
||||
if (colorsShortNames[colorName] != null) {
|
||||
val = colorsShortNames[colorName];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'convertEllipseToCircle';
|
||||
exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
|
||||
export const name = 'convertEllipseToCircle';
|
||||
export const description = 'converts non-eccentric <ellipse>s to <circle>s';
|
||||
|
||||
/**
|
||||
* Converts non-eccentric <ellipse>s to <circle>s.
|
||||
@ -10,9 +8,9 @@ exports.description = 'converts non-eccentric <ellipse>s to <circle>s';
|
||||
*
|
||||
* @author Taylor Hunt
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'convertEllipseToCircle'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'convertEllipseToCircle'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
|
@ -1,31 +1,29 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').XastParent} XastParent
|
||||
*/
|
||||
|
||||
const { attrsGroupsDefaults, colorsProps } = require('./_collections');
|
||||
const {
|
||||
import { attrsGroupsDefaults, colorsProps } from './_collections.js';
|
||||
import {
|
||||
detachNodeFromParent,
|
||||
querySelectorAll,
|
||||
querySelector,
|
||||
} = require('../lib/xast');
|
||||
const { computeStyle, collectStylesheet } = require('../lib/style');
|
||||
} from '../lib/xast.js';
|
||||
import { computeStyle, collectStylesheet } from '../lib/style.js';
|
||||
|
||||
exports.name = 'convertOneStopGradients';
|
||||
exports.description =
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastParent} XastParent
|
||||
*/
|
||||
|
||||
export const name = 'convertOneStopGradients';
|
||||
export const description =
|
||||
'converts one-stop (single color) gradients to a plain color';
|
||||
|
||||
/**
|
||||
* Converts one-stop (single color) gradients to a plain color.
|
||||
*
|
||||
* @author Seth Falco <seth@falco.fun>
|
||||
* @type {import('./plugins-types').Plugin<'convertOneStopGradients'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'convertOneStopGradients'>}
|
||||
* @see https://developer.mozilla.org/docs/Web/SVG/Element/linearGradient
|
||||
* @see https://developer.mozilla.org/docs/Web/SVG/Element/radialGradient
|
||||
*/
|
||||
exports.fn = (root) => {
|
||||
export const fn = (root) => {
|
||||
const stylesheet = collectStylesheet(root);
|
||||
|
||||
/**
|
||||
|
@ -1,18 +1,16 @@
|
||||
'use strict';
|
||||
import { path2js, js2path } from './_path.js';
|
||||
import { pathElems } from './_collections.js';
|
||||
import { applyTransforms } from './applyTransforms.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
import { visit } from '../lib/xast.js';
|
||||
import { cleanupOutData, toFixed } from '../lib/svgo/tools.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib//types').PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types.js').PathDataItem} PathDataItem
|
||||
*/
|
||||
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const { visit } = require('../lib/xast.js');
|
||||
const { pathElems } = require('./_collections.js');
|
||||
const { path2js, js2path } = require('./_path.js');
|
||||
const { applyTransforms } = require('./applyTransforms.js');
|
||||
const { cleanupOutData, toFixed } = require('../lib/svgo/tools');
|
||||
|
||||
exports.name = 'convertPathData';
|
||||
exports.description =
|
||||
export const name = 'convertPathData';
|
||||
export const description =
|
||||
'optimizes path data: writes in shorter form, applies transformations';
|
||||
|
||||
/** @type {(data: number[]) => number[]} */
|
||||
@ -75,9 +73,9 @@ let arcTolerance;
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'convertPathData'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'convertPathData'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const {
|
||||
// TODO convert to separate plugin in v3
|
||||
applyTransforms: _applyTransforms = true,
|
||||
|
@ -1,14 +1,12 @@
|
||||
'use strict';
|
||||
import { stringifyPathData } from '../lib/path.js';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types.js').PathDataItem} PathDataItem
|
||||
*/
|
||||
|
||||
const { stringifyPathData } = require('../lib/path.js');
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'convertShapeToPath';
|
||||
exports.description = 'converts basic shapes to more compact path form';
|
||||
export const name = 'convertShapeToPath';
|
||||
export const description = 'converts basic shapes to more compact path form';
|
||||
|
||||
const regNumber = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
|
||||
|
||||
@ -21,9 +19,9 @@ const regNumber = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
|
||||
*
|
||||
* @author Lev Solntsev
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'convertShapeToPath'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'convertShapeToPath'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const { convertArcs = false, floatPrecision: precision } = params;
|
||||
|
||||
return {
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { attrsGroups } from './_collections.js';
|
||||
|
||||
const { attrsGroups } = require('./_collections');
|
||||
|
||||
exports.name = 'convertStyleToAttrs';
|
||||
exports.description = 'converts style to attributes';
|
||||
export const name = 'convertStyleToAttrs';
|
||||
export const description = 'converts style to attributes';
|
||||
|
||||
/**
|
||||
* @type {(...args: string[]) => string}
|
||||
@ -65,9 +63,9 @@ const regStripComments = new RegExp(
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'convertStyleToAttrs'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'convertStyleToAttrs'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const { keepImportant = false } = params;
|
||||
return {
|
||||
element: {
|
||||
|
@ -1,20 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastChild} XastChild
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').XastParent} XastParent
|
||||
*/
|
||||
|
||||
const { cleanupOutData, toFixed } = require('../lib/svgo/tools.js');
|
||||
const {
|
||||
import { cleanupOutData, toFixed } from '../lib/svgo/tools.js';
|
||||
import {
|
||||
transform2js,
|
||||
transformsMultiply,
|
||||
matrixToTransform,
|
||||
} = require('./_transforms.js');
|
||||
} from './_transforms.js';
|
||||
|
||||
exports.name = 'convertTransform';
|
||||
exports.description = 'collapses multiple transformations and optimizes it';
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').XastChild} XastChild
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastParent} XastParent
|
||||
*/
|
||||
|
||||
export const name = 'convertTransform';
|
||||
export const description =
|
||||
'collapses multiple transformations and optimizes it';
|
||||
|
||||
/**
|
||||
* Convert matrices to the short aliases,
|
||||
@ -26,9 +25,9 @@ exports.description = 'collapses multiple transformations and optimizes it';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'convertTransform'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'convertTransform'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const {
|
||||
convertToShorts = true,
|
||||
// degPrecision = 3, // transformPrecision (or matrix precision) - 2 by default
|
||||
|
@ -1,24 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').XastParent} XastParent
|
||||
*/
|
||||
|
||||
const csstree = require('css-tree');
|
||||
const {
|
||||
syntax: { specificity },
|
||||
} = require('csso');
|
||||
const {
|
||||
import * as csstree from 'css-tree';
|
||||
import { syntax } from 'csso';
|
||||
import { attrsGroups, pseudoClasses } from './_collections.js';
|
||||
import {
|
||||
visitSkip,
|
||||
querySelectorAll,
|
||||
detachNodeFromParent,
|
||||
} = require('../lib/xast.js');
|
||||
const { compareSpecificity, includesAttrSelector } = require('../lib/style');
|
||||
const { attrsGroups, pseudoClasses } = require('./_collections');
|
||||
} from '../lib/xast.js';
|
||||
import { compareSpecificity, includesAttrSelector } from '../lib/style.js';
|
||||
|
||||
exports.name = 'inlineStyles';
|
||||
exports.description = 'inline styles (additional options)';
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastParent} XastParent
|
||||
*/
|
||||
|
||||
export const name = 'inlineStyles';
|
||||
export const description = 'inline styles (additional options)';
|
||||
|
||||
/**
|
||||
* Some pseudo-classes can only be calculated by clients, like :visited,
|
||||
@ -38,10 +34,10 @@ const preservedPseudos = [
|
||||
/**
|
||||
* Merges styles from style nodes into inline styles.
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'inlineStyles'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'inlineStyles'>}
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const {
|
||||
onlyMatchedOnce = true,
|
||||
removeMatchedSelectors = true,
|
||||
@ -177,8 +173,8 @@ exports.fn = (root, params) => {
|
||||
const sortedSelectors = selectors
|
||||
.slice()
|
||||
.sort((a, b) => {
|
||||
const aSpecificity = specificity(a.item.data);
|
||||
const bSpecificity = specificity(b.item.data);
|
||||
const aSpecificity = syntax.specificity(a.item.data);
|
||||
const bSpecificity = syntax.specificity(b.item.data);
|
||||
return compareSpecificity(aSpecificity, bSpecificity);
|
||||
})
|
||||
.reverse();
|
||||
|
@ -1,25 +1,23 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import("../lib/types").PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types').XastChild} XastChild
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import("../lib/types.js").PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types.js').XastChild} XastChild
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const { path2js, js2path, intersects } = require('./_path.js');
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
import { path2js, js2path, intersects } from './_path.js';
|
||||
|
||||
exports.name = 'mergePaths';
|
||||
exports.description = 'merges multiple paths in one if possible';
|
||||
export const name = 'mergePaths';
|
||||
export const description = 'merges multiple paths in one if possible';
|
||||
|
||||
/**
|
||||
* Merge multiple Paths into one.
|
||||
*
|
||||
* @author Kir Belevich, Lev Solntsev
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'mergePaths'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'mergePaths'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const {
|
||||
force = false,
|
||||
floatPrecision,
|
||||
|
@ -1,23 +1,21 @@
|
||||
'use strict';
|
||||
import { visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').XastChild} XastChild
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastChild} XastChild
|
||||
*/
|
||||
|
||||
const { visitSkip, detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'mergeStyles';
|
||||
exports.description = 'merge multiple style elements into one';
|
||||
export const name = 'mergeStyles';
|
||||
export const description = 'merge multiple style elements into one';
|
||||
|
||||
/**
|
||||
* Merge multiple style elements into one.
|
||||
*
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'mergeStyles'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'mergeStyles'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
/**
|
||||
* @type {?XastElement}
|
||||
*/
|
||||
|
@ -1,24 +1,22 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').XastParent} XastParent
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastParent} XastParent
|
||||
*/
|
||||
|
||||
const csso = require('csso');
|
||||
const { detachNodeFromParent } = require('../lib/xast');
|
||||
const { hasScripts } = require('../lib/svgo/tools');
|
||||
import * as csso from 'csso';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
import { hasScripts } from '../lib/svgo/tools.js';
|
||||
|
||||
exports.name = 'minifyStyles';
|
||||
exports.description = 'minifies styles and removes unused styles';
|
||||
export const name = 'minifyStyles';
|
||||
export const description = 'minifies styles and removes unused styles';
|
||||
|
||||
/**
|
||||
* Minifies styles (<style> element + style attribute) using CSSO.
|
||||
*
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
* @type {import('./plugins-types').Plugin<'minifyStyles'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'minifyStyles'>}
|
||||
*/
|
||||
exports.fn = (_root, { usage, ...params }) => {
|
||||
export const fn = (_root, { usage, ...params }) => {
|
||||
/** @type {Map<XastElement, XastParent>} */
|
||||
const styleElements = new Map();
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
'use strict';
|
||||
import { visit } from '../lib/xast.js';
|
||||
import { inheritableAttrs, pathElems } from './_collections.js';
|
||||
|
||||
const { visit } = require('../lib/xast.js');
|
||||
const { inheritableAttrs, pathElems } = require('./_collections.js');
|
||||
|
||||
exports.name = 'moveElemsAttrsToGroup';
|
||||
exports.description = 'Move common attributes of group children to the group';
|
||||
export const name = 'moveElemsAttrsToGroup';
|
||||
export const description =
|
||||
'Move common attributes of group children to the group';
|
||||
|
||||
/**
|
||||
* Move common attributes of group children to the group
|
||||
@ -26,9 +25,9 @@ exports.description = 'Move common attributes of group children to the group';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'moveElemsAttrsToGroup'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'moveElemsAttrsToGroup'>}
|
||||
*/
|
||||
exports.fn = (root) => {
|
||||
export const fn = (root) => {
|
||||
// find if any style element is present
|
||||
let deoptimizedWithStyles = false;
|
||||
visit(root, {
|
||||
|
@ -1,10 +1,9 @@
|
||||
'use strict';
|
||||
import { pathElems, referencesProps } from './_collections.js';
|
||||
import { includesUrlReference } from '../lib/svgo/tools.js';
|
||||
|
||||
const { pathElems, referencesProps } = require('./_collections.js');
|
||||
const { includesUrlReference } = require('../lib/svgo/tools.js');
|
||||
|
||||
exports.name = 'moveGroupAttrsToElems';
|
||||
exports.description = 'moves some group attributes to the content elements';
|
||||
export const name = 'moveGroupAttrsToElems';
|
||||
export const description =
|
||||
'moves some group attributes to the content elements';
|
||||
|
||||
const pathElemsWithGroupsAndText = [...pathElems, 'g', 'text'];
|
||||
|
||||
@ -24,9 +23,9 @@ const pathElemsWithGroupsAndText = [...pathElems, 'g', 'text'];
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'moveGroupAttrsToElems'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'moveGroupAttrsToElems'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
|
2
plugins/plugins-types.d.ts
vendored
2
plugins/plugins-types.d.ts
vendored
@ -2,7 +2,7 @@ import type {
|
||||
Plugin as PluginDef,
|
||||
PluginInfo,
|
||||
XastElement,
|
||||
} from '../lib/types';
|
||||
} from '../lib/types.js';
|
||||
|
||||
type DefaultPlugins = {
|
||||
cleanupAttrs: {
|
||||
|
@ -1,15 +1,13 @@
|
||||
'use strict';
|
||||
import * as csstree from 'css-tree';
|
||||
import { referencesProps } from './_collections.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types.js').PluginInfo} PluginInfo
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
const csstree = require('css-tree');
|
||||
const { referencesProps } = require('./_collections.js');
|
||||
|
||||
exports.name = 'prefixIds';
|
||||
exports.description = 'prefix IDs';
|
||||
export const name = 'prefixIds';
|
||||
export const description = 'prefix IDs';
|
||||
|
||||
/**
|
||||
* extract basename from path
|
||||
@ -118,9 +116,9 @@ const generatePrefix = (body, node, info, prefixGenerator, delim, history) => {
|
||||
* Prefixes identifiers
|
||||
*
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
* @type {import('./plugins-types').Plugin<'prefixIds'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'prefixIds'>}
|
||||
*/
|
||||
exports.fn = (_root, params, info) => {
|
||||
export const fn = (_root, params, info) => {
|
||||
const {
|
||||
delim = '__',
|
||||
prefix,
|
||||
|
@ -1,42 +1,39 @@
|
||||
'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 sortAttrs = require('./sortAttrs.js');
|
||||
const sortDefsChildren = require('./sortDefsChildren.js');
|
||||
const removeTitle = require('./removeTitle.js');
|
||||
const removeDesc = require('./removeDesc.js');
|
||||
import { createPreset } from '../lib/svgo/plugins.js';
|
||||
import * as removeDoctype from './removeDoctype.js';
|
||||
import * as removeXMLProcInst from './removeXMLProcInst.js';
|
||||
import * as removeComments from './removeComments.js';
|
||||
import * as removeMetadata from './removeMetadata.js';
|
||||
import * as removeEditorsNSData from './removeEditorsNSData.js';
|
||||
import * as cleanupAttrs from './cleanupAttrs.js';
|
||||
import * as mergeStyles from './mergeStyles.js';
|
||||
import * as inlineStyles from './inlineStyles.js';
|
||||
import * as minifyStyles from './minifyStyles.js';
|
||||
import * as cleanupIds from './cleanupIds.js';
|
||||
import * as removeUselessDefs from './removeUselessDefs.js';
|
||||
import * as cleanupNumericValues from './cleanupNumericValues.js';
|
||||
import * as convertColors from './convertColors.js';
|
||||
import * as removeUnknownsAndDefaults from './removeUnknownsAndDefaults.js';
|
||||
import * as removeNonInheritableGroupAttrs from './removeNonInheritableGroupAttrs.js';
|
||||
import * as removeUselessStrokeAndFill from './removeUselessStrokeAndFill.js';
|
||||
import * as removeViewBox from './removeViewBox.js';
|
||||
import * as cleanupEnableBackground from './cleanupEnableBackground.js';
|
||||
import * as removeHiddenElems from './removeHiddenElems.js';
|
||||
import * as removeEmptyText from './removeEmptyText.js';
|
||||
import * as convertShapeToPath from './convertShapeToPath.js';
|
||||
import * as convertEllipseToCircle from './convertEllipseToCircle.js';
|
||||
import * as moveElemsAttrsToGroup from './moveElemsAttrsToGroup.js';
|
||||
import * as moveGroupAttrsToElems from './moveGroupAttrsToElems.js';
|
||||
import * as collapseGroups from './collapseGroups.js';
|
||||
import * as convertPathData from './convertPathData.js';
|
||||
import * as convertTransform from './convertTransform.js';
|
||||
import * as removeEmptyAttrs from './removeEmptyAttrs.js';
|
||||
import * as removeEmptyContainers from './removeEmptyContainers.js';
|
||||
import * as mergePaths from './mergePaths.js';
|
||||
import * as removeUnusedNS from './removeUnusedNS.js';
|
||||
import * as sortAttrs from './sortAttrs.js';
|
||||
import * as sortDefsChildren from './sortDefsChildren.js';
|
||||
import * as removeTitle from './removeTitle.js';
|
||||
import * as removeDesc from './removeDesc.js';
|
||||
|
||||
const presetDefault = createPreset({
|
||||
name: 'preset-default',
|
||||
@ -79,4 +76,4 @@ const presetDefault = createPreset({
|
||||
],
|
||||
});
|
||||
|
||||
module.exports = presetDefault;
|
||||
export default presetDefault;
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { querySelectorAll } from '../lib/xast.js';
|
||||
|
||||
const { querySelectorAll } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeAttributesBySelector';
|
||||
exports.description =
|
||||
export const name = 'removeAttributesBySelector';
|
||||
export const description =
|
||||
'removes attributes of elements that match a css selector';
|
||||
|
||||
/**
|
||||
@ -73,9 +71,9 @@ exports.description =
|
||||
*
|
||||
* @author Bradley Mease
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeAttributesBySelector'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeAttributesBySelector'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const selectors = Array.isArray(params.selectors)
|
||||
? params.selectors
|
||||
: [params];
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeAttrs';
|
||||
exports.description = 'removes specified attributes';
|
||||
export const name = 'removeAttrs';
|
||||
export const description = 'removes specified attributes';
|
||||
|
||||
const DEFAULT_SEPARATOR = ':';
|
||||
const ENOATTRS = `Warning: The plugin "removeAttrs" requires the "attrs" parameter.
|
||||
@ -81,9 +79,9 @@ plugins: [
|
||||
*
|
||||
* @author Benny Schudel
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeAttrs'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeAttrs'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
if (typeof params.attrs == 'undefined') {
|
||||
console.warn(ENOATTRS);
|
||||
return null;
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeComments';
|
||||
exports.description = 'removes comments';
|
||||
export const name = 'removeComments';
|
||||
export const description = 'removes comments';
|
||||
|
||||
/**
|
||||
* If a comment matches one of the following patterns, it will be
|
||||
@ -20,9 +18,9 @@ const DEFAULT_PRESERVE_PATTERNS = [/^!/];
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeComments'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeComments'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const { preservePatterns = DEFAULT_PRESERVE_PATTERNS } = params;
|
||||
|
||||
return {
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeDesc';
|
||||
exports.description = 'removes <desc>';
|
||||
export const name = 'removeDesc';
|
||||
export const description = 'removes <desc>';
|
||||
|
||||
const standardDescs = /^(Created with|Created using)/;
|
||||
|
||||
@ -16,9 +14,9 @@ const standardDescs = /^(Created with|Created using)/;
|
||||
*
|
||||
* @author Daniel Wabyick
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeDesc'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeDesc'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const { removeAny = false } = params;
|
||||
return {
|
||||
element: {
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeDimensions';
|
||||
exports.description =
|
||||
export const name = 'removeDimensions';
|
||||
export const description =
|
||||
'removes width and height in presence of viewBox (opposite to removeViewBox, disable it first)';
|
||||
|
||||
/**
|
||||
@ -14,9 +12,9 @@ exports.description =
|
||||
*
|
||||
* @author Benny Schudel
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeDimensions'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeDimensions'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeDoctype';
|
||||
exports.description = 'removes doctype declaration';
|
||||
export const name = 'removeDoctype';
|
||||
export const description = 'removes doctype declaration';
|
||||
|
||||
/**
|
||||
* Remove DOCTYPE declaration.
|
||||
@ -27,9 +25,9 @@ exports.description = 'removes doctype declaration';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeDoctype'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeDoctype'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
doctype: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,10 +1,9 @@
|
||||
'use strict';
|
||||
import { editorNamespaces } from './_collections.js';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { editorNamespaces } = require('./_collections.js');
|
||||
|
||||
exports.name = 'removeEditorsNSData';
|
||||
exports.description = 'removes editors namespaces, elements and attributes';
|
||||
export const name = 'removeEditorsNSData';
|
||||
export const description =
|
||||
'removes editors namespaces, elements and attributes';
|
||||
|
||||
/**
|
||||
* Remove editors namespaces, elements and attributes.
|
||||
@ -16,9 +15,9 @@ exports.description = 'removes editors namespaces, elements and attributes';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeEditorsNSData'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeEditorsNSData'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
let namespaces = [...editorNamespaces];
|
||||
if (Array.isArray(params.additionalNamespaces)) {
|
||||
namespaces = [...editorNamespaces, ...params.additionalNamespaces];
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeElementsByAttr';
|
||||
exports.description =
|
||||
export const name = 'removeElementsByAttr';
|
||||
export const description =
|
||||
'removes arbitrary elements by ID or className (disabled by default)';
|
||||
|
||||
/**
|
||||
@ -37,9 +35,9 @@ exports.description =
|
||||
*
|
||||
* @author Eli Dupuis (@elidupuis)
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeElementsByAttr'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeElementsByAttr'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const ids =
|
||||
params.id == null ? [] : Array.isArray(params.id) ? params.id : [params.id];
|
||||
const classes =
|
||||
|
@ -1,18 +1,16 @@
|
||||
'use strict';
|
||||
import { attrsGroups } from './_collections.js';
|
||||
|
||||
const { attrsGroups } = require('./_collections.js');
|
||||
|
||||
exports.name = 'removeEmptyAttrs';
|
||||
exports.description = 'removes empty attributes';
|
||||
export const name = 'removeEmptyAttrs';
|
||||
export const description = 'removes empty attributes';
|
||||
|
||||
/**
|
||||
* Remove attributes with empty values.
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeEmptyAttrs'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeEmptyAttrs'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
|
@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
import { elemsGroups } from './_collections.js';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { elemsGroups } = require('./_collections.js');
|
||||
|
||||
exports.name = 'removeEmptyContainers';
|
||||
exports.description = 'removes empty container elements';
|
||||
export const name = 'removeEmptyContainers';
|
||||
export const description = 'removes empty container elements';
|
||||
|
||||
/**
|
||||
* Remove empty containers.
|
||||
@ -19,9 +17,9 @@ exports.description = 'removes empty container elements';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeEmptyContainers'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeEmptyContainers'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
exit: (node, parentNode) => {
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeEmptyText';
|
||||
exports.description = 'removes empty <text> elements';
|
||||
export const name = 'removeEmptyText';
|
||||
export const description = 'removes empty <text> elements';
|
||||
|
||||
/**
|
||||
* Remove empty Text elements.
|
||||
@ -22,9 +20,9 @@ exports.description = 'removes empty <text> elements';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeEmptyText'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeEmptyText'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const { text = true, tspan = true, tref = true } = params;
|
||||
return {
|
||||
element: {
|
||||
|
@ -1,26 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastChild} XastChild
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').XastParent} XastParent
|
||||
* @typedef {import('../lib/types.js').XastChild} XastChild
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastParent} XastParent
|
||||
*/
|
||||
|
||||
const { elemsGroups } = require('./_collections.js');
|
||||
const {
|
||||
import { elemsGroups } from './_collections.js';
|
||||
import {
|
||||
visit,
|
||||
visitSkip,
|
||||
querySelector,
|
||||
detachNodeFromParent,
|
||||
} = require('../lib/xast.js');
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const { parsePathData } = require('../lib/path.js');
|
||||
const { hasScripts, findReferences } = require('../lib/svgo/tools.js');
|
||||
} 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';
|
||||
|
||||
const nonRendering = elemsGroups.nonRendering;
|
||||
|
||||
exports.name = 'removeHiddenElems';
|
||||
exports.description =
|
||||
export const name = 'removeHiddenElems';
|
||||
export const description =
|
||||
'removes hidden elements (zero sized, with absent attributes)';
|
||||
|
||||
/**
|
||||
@ -38,9 +36,9 @@ exports.description =
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeHiddenElems'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeHiddenElems'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const {
|
||||
isHidden = true,
|
||||
displayNone = true,
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeMetadata';
|
||||
exports.description = 'removes <metadata>';
|
||||
export const name = 'removeMetadata';
|
||||
export const description = 'removes <metadata>';
|
||||
|
||||
/**
|
||||
* Remove <metadata>.
|
||||
@ -12,9 +10,9 @@ exports.description = 'removes <metadata>';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeMetadata'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeMetadata'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,13 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
import {
|
||||
inheritableAttrs,
|
||||
attrsGroups,
|
||||
presentationNonInheritableGroupAttrs,
|
||||
} = require('./_collections');
|
||||
} from './_collections.js';
|
||||
|
||||
exports.name = 'removeNonInheritableGroupAttrs';
|
||||
exports.description =
|
||||
export const name = 'removeNonInheritableGroupAttrs';
|
||||
export const description =
|
||||
'removes non-inheritable group’s presentational attributes';
|
||||
|
||||
/**
|
||||
@ -15,9 +13,9 @@ exports.description =
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeNonInheritableGroupAttrs'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeNonInheritableGroupAttrs'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
|
@ -1,15 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').PathDataItem} PathDataItem
|
||||
* @typedef {import('../lib/types.js').PathDataItem} PathDataItem
|
||||
*/
|
||||
|
||||
const { visitSkip, detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { parsePathData } = require('../lib/path.js');
|
||||
const { intersects } = require('./_path.js');
|
||||
import { visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
import { parsePathData } from '../lib/path.js';
|
||||
import { intersects } from './_path.js';
|
||||
|
||||
exports.name = 'removeOffCanvasPaths';
|
||||
exports.description =
|
||||
export const name = 'removeOffCanvasPaths';
|
||||
export const description =
|
||||
'removes elements that are drawn outside of the viewbox (disabled by default)';
|
||||
|
||||
/**
|
||||
@ -17,9 +15,9 @@ exports.description =
|
||||
*
|
||||
* @author JoshyPHP
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeOffCanvasPaths'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeOffCanvasPaths'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
/**
|
||||
* @type {?{
|
||||
* top: number,
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeRasterImages';
|
||||
exports.description = 'removes raster images (disabled by default)';
|
||||
export const name = 'removeRasterImages';
|
||||
export const description = 'removes raster images (disabled by default)';
|
||||
|
||||
/**
|
||||
* Remove raster images references in <image>.
|
||||
@ -12,9 +10,9 @@ exports.description = 'removes raster images (disabled by default)';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeRasterImages'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeRasterImages'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,10 +1,8 @@
|
||||
'use strict';
|
||||
import { attrsGroups } from './_collections.js';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { attrsGroups } = require('./_collections.js');
|
||||
|
||||
exports.name = 'removeScriptElement';
|
||||
exports.description = 'removes scripts (disabled by default)';
|
||||
export const name = 'removeScriptElement';
|
||||
export const description = 'removes scripts (disabled by default)';
|
||||
|
||||
/** Union of all event attributes. */
|
||||
const eventAttrs = [
|
||||
@ -21,9 +19,9 @@ const eventAttrs = [
|
||||
* https://www.w3.org/TR/SVG11/script.html
|
||||
*
|
||||
* @author Patrick Klingemann
|
||||
* @type {import('./plugins-types').Plugin<'removeScriptElement'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeScriptElement'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeStyleElement';
|
||||
exports.description = 'removes <style> element (disabled by default)';
|
||||
export const name = 'removeStyleElement';
|
||||
export const description = 'removes <style> element (disabled by default)';
|
||||
|
||||
/**
|
||||
* Remove <style>.
|
||||
@ -12,9 +10,9 @@ exports.description = 'removes <style> element (disabled by default)';
|
||||
*
|
||||
* @author Betsy Dupuis
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeStyleElement'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeStyleElement'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeTitle';
|
||||
exports.description = 'removes <title>';
|
||||
export const name = 'removeTitle';
|
||||
export const description = 'removes <title>';
|
||||
|
||||
/**
|
||||
* Remove <title>.
|
||||
@ -12,9 +10,9 @@ exports.description = 'removes <title>';
|
||||
*
|
||||
* @author Igor Kalashnikov
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeTitle'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeTitle'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,17 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
const { visitSkip, detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const {
|
||||
import {
|
||||
elems,
|
||||
attrsGroups,
|
||||
elemsGroups,
|
||||
attrsGroupsDefaults,
|
||||
presentationNonInheritableGroupAttrs,
|
||||
} = require('./_collections');
|
||||
} from './_collections.js';
|
||||
import { visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
|
||||
exports.name = 'removeUnknownsAndDefaults';
|
||||
exports.description =
|
||||
export const name = 'removeUnknownsAndDefaults';
|
||||
export const description =
|
||||
'removes unknown elements content and attributes, removes attrs with default values';
|
||||
|
||||
// resolve all groups references
|
||||
@ -92,9 +90,9 @@ for (const [name, config] of Object.entries(elems)) {
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeUnknownsAndDefaults'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeUnknownsAndDefaults'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const {
|
||||
unknownContent = true,
|
||||
unknownAttrs = true,
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeUnusedNS';
|
||||
exports.description = 'removes unused namespaces declaration';
|
||||
export const name = 'removeUnusedNS';
|
||||
export const description = 'removes unused namespaces declaration';
|
||||
|
||||
/**
|
||||
* Remove unused namespaces declaration from svg element
|
||||
@ -9,9 +7,9 @@ exports.description = 'removes unused namespaces declaration';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeUnusedNS'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeUnusedNS'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
/**
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
|
@ -1,23 +1,21 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
import { elemsGroups } from './_collections.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { elemsGroups } = require('./_collections.js');
|
||||
|
||||
exports.name = 'removeUselessDefs';
|
||||
exports.description = 'removes elements in <defs> without id';
|
||||
export const name = 'removeUselessDefs';
|
||||
export const description = 'removes elements in <defs> without id';
|
||||
|
||||
/**
|
||||
* Removes content of defs and properties that aren't rendered directly without ids.
|
||||
*
|
||||
* @author Lev Solntsev
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeUselessDefs'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeUselessDefs'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,21 +1,19 @@
|
||||
'use strict';
|
||||
import { visit, visitSkip, detachNodeFromParent } from '../lib/xast.js';
|
||||
import { collectStylesheet, computeStyle } from '../lib/style.js';
|
||||
import { hasScripts } from '../lib/svgo/tools.js';
|
||||
import { elemsGroups } from './_collections.js';
|
||||
|
||||
const { visit, visitSkip, detachNodeFromParent } = require('../lib/xast.js');
|
||||
const { collectStylesheet, computeStyle } = require('../lib/style.js');
|
||||
const { hasScripts } = require('../lib/svgo/tools.js');
|
||||
const { elemsGroups } = require('./_collections.js');
|
||||
|
||||
exports.name = 'removeUselessStrokeAndFill';
|
||||
exports.description = 'removes useless stroke and fill attributes';
|
||||
export const name = 'removeUselessStrokeAndFill';
|
||||
export const description = 'removes useless stroke and fill attributes';
|
||||
|
||||
/**
|
||||
* Remove useless stroke and fill attrs.
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeUselessStrokeAndFill'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeUselessStrokeAndFill'>}
|
||||
*/
|
||||
exports.fn = (root, params) => {
|
||||
export const fn = (root, params) => {
|
||||
const {
|
||||
stroke: removeStroke = true,
|
||||
fill: removeFill = true,
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeViewBox';
|
||||
exports.description = 'removes viewBox attribute when possible';
|
||||
export const name = 'removeViewBox';
|
||||
export const description = 'removes viewBox attribute when possible';
|
||||
|
||||
const viewBoxElems = new Set(['pattern', 'svg', 'symbol']);
|
||||
|
||||
@ -17,9 +15,9 @@ const viewBoxElems = new Set(['pattern', 'svg', 'symbol']);
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeViewBox'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeViewBox'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'removeXMLNS';
|
||||
exports.description =
|
||||
export const name = 'removeXMLNS';
|
||||
export const description =
|
||||
'removes xmlns attribute (for inline svg, disabled by default)';
|
||||
|
||||
/**
|
||||
@ -14,9 +12,9 @@ exports.description =
|
||||
*
|
||||
* @author Ricardo Tomasi
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeXMLNS'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeXMLNS'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
|
@ -1,9 +1,7 @@
|
||||
'use strict';
|
||||
import { detachNodeFromParent } from '../lib/xast.js';
|
||||
|
||||
const { detachNodeFromParent } = require('../lib/xast.js');
|
||||
|
||||
exports.name = 'removeXMLProcInst';
|
||||
exports.description = 'removes XML processing instructions';
|
||||
export const name = 'removeXMLProcInst';
|
||||
export const description = 'removes XML processing instructions';
|
||||
|
||||
/**
|
||||
* Remove XML Processing Instruction.
|
||||
@ -13,9 +11,9 @@ exports.description = 'removes XML processing instructions';
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeXMLProcInst'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeXMLProcInst'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
instruction: {
|
||||
enter: (node, parentNode) => {
|
||||
|
@ -1,13 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const { elems } = require('./_collections');
|
||||
import { elems } from './_collections.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
*/
|
||||
|
||||
exports.name = 'removeXlink';
|
||||
exports.description =
|
||||
export const name = 'removeXlink';
|
||||
export const description =
|
||||
'remove xlink namespace and replaces attributes with the SVG 2 equivalent where applicable';
|
||||
|
||||
/** URI indicating the Xlink namespace. */
|
||||
@ -58,10 +56,10 @@ const findPrefixedAttrs = (node, prefixes, attr) => {
|
||||
*
|
||||
* The XLink namespace is deprecated in SVG 2.
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'removeXlink'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'removeXlink'>}
|
||||
* @see https://developer.mozilla.org/docs/Web/SVG/Attribute/xlink:href
|
||||
*/
|
||||
exports.fn = (_, params) => {
|
||||
export const fn = (_, params) => {
|
||||
const { includeLegacy } = params;
|
||||
|
||||
/**
|
||||
|
@ -1,16 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
const { collectStylesheet } = require('../lib/style');
|
||||
const { detachNodeFromParent, querySelectorAll } = require('../lib/xast');
|
||||
import { collectStylesheet } from '../lib/style.js';
|
||||
import { detachNodeFromParent, querySelectorAll } from '../lib/xast.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../lib/types').XastElement} XastElement
|
||||
* @typedef {import('../lib/types').XastParent} XastParent
|
||||
* @typedef {import('../lib/types').XastNode} XastNode
|
||||
* @typedef {import('../lib/types.js').XastElement} XastElement
|
||||
* @typedef {import('../lib/types.js').XastParent} XastParent
|
||||
* @typedef {import('../lib/types.js').XastNode} XastNode
|
||||
*/
|
||||
|
||||
exports.name = 'reusePaths';
|
||||
exports.description =
|
||||
export const name = 'reusePaths';
|
||||
export const description =
|
||||
'Finds <path> elements with the same d, fill, and ' +
|
||||
'stroke, and converts them to <use> elements ' +
|
||||
'referencing a single <path> def.';
|
||||
@ -21,9 +19,9 @@ exports.description =
|
||||
*
|
||||
* @author Jacob Howcroft
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'reusePaths'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'reusePaths'>}
|
||||
*/
|
||||
exports.fn = (root) => {
|
||||
export const fn = (root) => {
|
||||
const stylesheet = collectStylesheet(root);
|
||||
|
||||
/**
|
||||
|
@ -1,16 +1,14 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'sortAttrs';
|
||||
exports.description = 'Sort element attributes for better compression';
|
||||
export const name = 'sortAttrs';
|
||||
export const description = 'Sort element attributes for better compression';
|
||||
|
||||
/**
|
||||
* Sort element attributes for better compression
|
||||
*
|
||||
* @author Nikolay Frantsev
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'sortAttrs'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'sortAttrs'>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
export const fn = (_root, params) => {
|
||||
const {
|
||||
order = [
|
||||
'id',
|
||||
|
@ -1,7 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
exports.name = 'sortDefsChildren';
|
||||
exports.description = 'Sorts children of <defs> to improve compression';
|
||||
export const name = 'sortDefsChildren';
|
||||
export const description = 'Sorts children of <defs> to improve compression';
|
||||
|
||||
/**
|
||||
* Sorts children of defs in order to improve compression.
|
||||
@ -9,9 +7,9 @@ exports.description = 'Sorts children of <defs> to improve compression';
|
||||
*
|
||||
* @author David Leston
|
||||
*
|
||||
* @type {import('./plugins-types').Plugin<'sortDefsChildren'>}
|
||||
* @type {import('./plugins-types.js').Plugin<'sortDefsChildren'>}
|
||||
*/
|
||||
exports.fn = () => {
|
||||
export const fn = () => {
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
|
@ -1,25 +1,44 @@
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import * as fs from 'node:fs';
|
||||
import { nodeResolve } from '@rollup/plugin-node-resolve';
|
||||
import commonjs from '@rollup/plugin-commonjs';
|
||||
import { terser } from 'rollup-plugin-terser';
|
||||
import terser from '@rollup/plugin-terser';
|
||||
|
||||
export default {
|
||||
input: './lib/svgo.js',
|
||||
output: {
|
||||
file: './dist/svgo.browser.js',
|
||||
format: 'esm',
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
const pkgPath = path.join(__dirname, './package.json');
|
||||
const PKG = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
||||
|
||||
export default [
|
||||
{
|
||||
input: './lib/svgo.js',
|
||||
output: {
|
||||
file: './dist/svgo-node.cjs',
|
||||
format: 'cjs',
|
||||
},
|
||||
external: Object.keys(PKG.dependencies),
|
||||
onwarn(warning) {
|
||||
throw Error(warning.toString());
|
||||
},
|
||||
plugins: [terser()],
|
||||
},
|
||||
onwarn(warning) {
|
||||
throw Error(warning.toString());
|
||||
{
|
||||
input: './lib/svgo.js',
|
||||
output: {
|
||||
file: './dist/svgo.browser.js',
|
||||
format: 'esm',
|
||||
},
|
||||
onwarn(warning) {
|
||||
throw Error(warning.toString());
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve({ browser: true, preferBuiltins: false }),
|
||||
commonjs(),
|
||||
terser({
|
||||
compress: false,
|
||||
mangle: false,
|
||||
format: { comments: false },
|
||||
}),
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
nodeResolve({ browser: true, preferBuiltins: false }),
|
||||
commonjs(),
|
||||
// Whitespaces and comments removal makes the browser bundle lighter
|
||||
// while retaining the ability to debug errors
|
||||
terser({
|
||||
compress: false,
|
||||
mangle: false,
|
||||
format: { comments: false },
|
||||
}),
|
||||
],
|
||||
};
|
||||
];
|
||||
|
@ -1,7 +1,7 @@
|
||||
const assert = require('assert');
|
||||
const fs = require('node:fs/promises');
|
||||
const http = require('http');
|
||||
const { chromium } = require('playwright');
|
||||
import assert from 'assert';
|
||||
import fs from 'node:fs/promises';
|
||||
import http from 'http';
|
||||
import { chromium } from 'playwright';
|
||||
|
||||
const fixture = `<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<g attr1="val1">
|
||||
|
@ -1,12 +1,13 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('child_process').ChildProcessWithoutNullStreams} ChildProcessWithoutNullStreams
|
||||
*/
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { spawn } = require('child_process');
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { spawn } from 'child_process';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
/**
|
||||
* @type {(proc: ChildProcessWithoutNullStreams) => Promise<string>}
|
||||
|
@ -1,10 +1,11 @@
|
||||
'use strict';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import del from 'del';
|
||||
import { Command } from 'commander';
|
||||
import { fileURLToPath } from 'url';
|
||||
import svgo, { checkIsDir } from '../../lib/svgo/coa.js';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const del = require('del');
|
||||
const { Command } = require('commander');
|
||||
const svgo = require('../../lib/svgo/coa.js');
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const svgFolderPath = path.resolve(__dirname, 'testSvg');
|
||||
const svgFolderPathRecursively = path.resolve(__dirname, 'testSvgRecursively');
|
||||
@ -15,8 +16,6 @@ const svgFiles = [
|
||||
const tempFolder = 'temp';
|
||||
const noop = () => {};
|
||||
|
||||
const { checkIsDir } = svgo;
|
||||
|
||||
function runProgram(args) {
|
||||
const program = new Command();
|
||||
svgo(program);
|
||||
|
2
test/fixtures/config-loader/invalid-array.js
vendored
2
test/fixtures/config-loader/invalid-array.js
vendored
@ -1 +1 @@
|
||||
module.exports = [];
|
||||
export default [];
|
||||
|
2
test/fixtures/config-loader/invalid-null.js
vendored
2
test/fixtures/config-loader/invalid-null.js
vendored
@ -1 +1 @@
|
||||
module.exports = null;
|
||||
export default null;
|
||||
|
@ -1 +1,2 @@
|
||||
module.exports = { plugins }; // eslint-disable-line no-undef
|
||||
/* eslint-disable no-undef */
|
||||
export default { plugins };
|
||||
|
@ -1 +1 @@
|
||||
module.exports = '';
|
||||
export default '';
|
||||
|
@ -1,2 +1,2 @@
|
||||
require('unknown-module');
|
||||
module.exports = {};
|
||||
import 'unknown-module';
|
||||
export default {};
|
||||
|
@ -1 +1 @@
|
||||
module.exports = { plugins: [] };
|
||||
export default { plugins: [] };
|
||||
|
2
test/fixtures/config-loader/svgo.config.js
vendored
2
test/fixtures/config-loader/svgo.config.js
vendored
@ -1 +1 @@
|
||||
module.exports = { plugins: [] };
|
||||
export default { plugins: [] };
|
||||
|
@ -1,11 +1,12 @@
|
||||
'use strict';
|
||||
import FS from 'fs';
|
||||
import PATH from 'path';
|
||||
import { EOL } from 'os';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { optimize } from '../../lib/svgo.js';
|
||||
|
||||
const FS = require('fs');
|
||||
const PATH = require('path');
|
||||
const EOL = require('os').EOL;
|
||||
const regEOL = new RegExp(EOL, 'g');
|
||||
const regFilename = /^(.*)\.(\d+)\.svg$/;
|
||||
const { optimize } = require('../../lib/svgo.js');
|
||||
const __dirname = PATH.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
describe('plugins tests', function () {
|
||||
FS.readdirSync(__dirname).forEach(function (file) {
|
||||
@ -41,7 +42,6 @@ describe('plugins tests', function () {
|
||||
js2svg: { pretty: true },
|
||||
});
|
||||
lastResultData = result.data;
|
||||
expect(result.error).not.toStrictEqual(expect.anything());
|
||||
//FIXME: results.data has a '\n' at the end while it should not
|
||||
expect(normalize(result.data)).toStrictEqual(should);
|
||||
}
|
||||
|
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const { matrixToTransform } = require('../../plugins/_transforms');
|
||||
import { matrixToTransform } from '../../plugins/_transforms.js';
|
||||
|
||||
/**
|
||||
* @typedef {import('../../plugins/_transforms').TransformParams} TransformParams
|
||||
|
@ -1,6 +1,4 @@
|
||||
'use strict';
|
||||
|
||||
const { optimize } = require('../../lib/svgo.js');
|
||||
import { optimize } from '../../lib/svgo.js';
|
||||
|
||||
test('should extract prefix from path basename', () => {
|
||||
const svg = `<svg id="my-id"></svg>`;
|
||||
|
@ -1,12 +1,13 @@
|
||||
'use strict';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import stream from 'stream';
|
||||
import util from 'util';
|
||||
import zlib from 'zlib';
|
||||
import fetch from 'node-fetch';
|
||||
import tarStream from 'tar-stream';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const stream = require('stream');
|
||||
const util = require('util');
|
||||
const zlib = require('zlib');
|
||||
const { default: fetch } = require('node-fetch');
|
||||
const tarStream = require('tar-stream');
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const pipeline = util.promisify(stream.pipeline);
|
||||
|
||||
|
@ -1,18 +1,19 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* @typedef {import('playwright').Page} Page
|
||||
* @typedef {import('playwright').PageScreenshotOptions} PageScreenshotOptions
|
||||
*/
|
||||
|
||||
const fs = require('node:fs/promises');
|
||||
const http = require('http');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const pixelmatch = require('pixelmatch');
|
||||
const { chromium } = require('playwright');
|
||||
const { PNG } = require('pngjs');
|
||||
const { optimize } = require('../lib/svgo.js');
|
||||
import fs from 'node:fs/promises';
|
||||
import http from 'http';
|
||||
import os from 'os';
|
||||
import path from 'path';
|
||||
import pixelmatch from 'pixelmatch';
|
||||
import { chromium } from 'playwright';
|
||||
import { PNG } from 'pngjs';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { optimize } from '../lib/svgo.js';
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const width = 960;
|
||||
const height = 720;
|
||||
|
@ -1,8 +1,9 @@
|
||||
'use strict';
|
||||
import FS from 'fs';
|
||||
import PATH from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
import { parseSvg } from '../../lib/parser.js';
|
||||
|
||||
const FS = require('fs');
|
||||
const PATH = require('path');
|
||||
const { parseSvg } = require('../../lib/parser.js');
|
||||
const __dirname = PATH.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
describe('svg2js', function () {
|
||||
describe('working svg', function () {
|
||||
|
33
test/svgo.cjs
Normal file
33
test/svgo.cjs
Normal file
@ -0,0 +1,33 @@
|
||||
const { optimize } = require('../dist/svgo-node.cjs');
|
||||
const assert = require('assert');
|
||||
|
||||
const fixture = `<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<g attr1="val1">
|
||||
<g attr2="val2">
|
||||
<path attr2="val3" d="..."/>
|
||||
</g>
|
||||
<path d="..."/>
|
||||
</g>
|
||||
</svg>`;
|
||||
|
||||
const expected = `<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<g attr1="val1">
|
||||
<g attr2="val2">
|
||||
<path attr2="val3" d="..."/>
|
||||
</g>
|
||||
<path d="..."/>
|
||||
</g>
|
||||
</svg>
|
||||
`;
|
||||
|
||||
const runTest = () => {
|
||||
const result = optimize(fixture, {
|
||||
plugins: [],
|
||||
js2svg: { pretty: true, indent: 2 },
|
||||
});
|
||||
const actual = result.data;
|
||||
|
||||
assert.equal(actual, expected);
|
||||
};
|
||||
|
||||
runTest();
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user