Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

svgo

Package Overview
Dependencies
Maintainers
3
Versions
104
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svgo - npm Package Compare versions

Comparing version 1.0.5 to 1.1.0

30

CHANGELOG.md

@@ -0,1 +1,29 @@

### [ [>](https://github.com/svg/svgo/tree/v1.1.0) ] 1.1.0 / 16.09.2018
* Fixed `collapseGroups` plugin removing property with a child having `inherit` value.
* `version` attribute value is not more being rounded.
* Fixed jsAPI `clone` method with respect to the introduced CSS classes.
* Fixed scaling strokes with `vector-effect="non-scaling-stroke"` (by @alexjlockwood).
* Fixed passing properties from groups in `collapseGroups` plugin if child have a filter (by @stristr).
* Fixed arc path commands parsing without separators after flags, effectively producing a JS error.
* Fixed `viewBox` separators parsing.
* Fixed `removeNonInheritableGroupAttrs` plugin to work as intended.
* Fixed removing path segments without length in presence of `stroke-linecap`.
* Fixed `removeUnknownsAndDefaults` plugin removing attributes from elements with `id`.
* Fixed converting to large arcs from nearly straight lines curves.
* Fixed `collapseGroups` plugin affecting `<switch>` and its subgroups.
* Fixed `convertTransform` plugin converting to `rotate()` with wrong sign in some case.
* Fixed `cleanupListOfValues` plugin not preserving non-numeric values.
* Fixed `!important` being passed to attributes in `convertStyleToAttrs` plugin.
* Added option `keepImportant` to `convertStyleToAttrs` plugin to preserve styles with `!important`.
* `removeHiddenElems` plugin now also removes elements with `visibility="hidden"` attribute (by @mikolaj92).
* Added `forceAbsolutePath` option to `convertPathData` plugin to always use absolute coordinates (by @cool).
* Added `keepRoleAttr` for `removeUnknownsAndDefaults` plugin to preserve `role-` attributes (by @himedlooff).
* Added `xmlns` order option in `sortAttrs` plugin (by @hellatan).
* Added an option to `prefixIds` plugin to pass prefix as false or as a function that returns false (by @vzaidman).
* `prefixIds` plugin now adds prefix to every class (by @vzaidman).
* Updated and improved docs a bit (multiple authors).
### [ [>](https://github.com/svg/svgo/tree/v1.0.5) ] 1.0.5 / 26.02.2018
* Fixed issue with prefixIDs plugin not replacing url() values correctly (by @harrisjose).
### [ [>](https://github.com/svg/svgo/tree/v1.0.4) ] 1.0.4 / 30.01.2018

@@ -35,3 +63,3 @@ * Fixed bug with removing groups that are direct child of "<switch>".

* `#ff0000` now converts to `red` as well as `#f00` (by @davidleston).
* Added “gray” variation to colors list per CSS Color Module Level 4 (by @JoshyPHP).
* Added “gray” variation to colors list per CSS Color Module Level 4 (by @ydaniv).
* Fixed error on empty files.

@@ -38,0 +66,0 @@ * A separator character in `removeAttrs` now can be changed per `elemSeparator` option (by @mikestreety).

10

lib/css-tools.js

@@ -18,3 +18,3 @@ 'use strict';

csstree.walkRules(cssAst, function(node) {
csstree.walk(cssAst, {visit: 'Rule', enter: function(node) {
if (node.type !== 'Rule') {

@@ -47,3 +47,3 @@ return;

});
});
}});

@@ -70,3 +70,3 @@ return selectors;

selector.atrule.expression.children.first().type === 'MediaQueryList') {
var mqExpr = csstree.translate(selector.atrule.expression);
var mqExpr = csstree.generate(selector.atrule.expression);
mqStr = [mqName, mqExpr].join(' ');

@@ -88,3 +88,3 @@ }

return selectors.filter(function(selector) {
var pseudoSelectorsStr = csstree.translate({
var pseudoSelectorsStr = csstree.generate({
type: 'Selector',

@@ -172,3 +172,3 @@ children: new List().fromArray(selector.pseudos.map(function(pseudo) {

var propertyName = declaration.property,
propertyValue = csstree.translate(declaration.value),
propertyValue = csstree.generate(declaration.value),
propertyPriority = (declaration.important ? 'important' : '');

@@ -175,0 +175,0 @@ return {

@@ -20,3 +20,3 @@ 'use strict';

var SVGO = module.exports = function(config) {
var SVGO = function(config) {
this.config = CONFIG(config);

@@ -49,2 +49,5 @@ };

}
if(info.path) {
svgjs.path = info.path;
}
resolve(svgjs);

@@ -82,1 +85,5 @@ }

};
module.exports = SVGO;
// Offer ES module interop compatibility.
module.exports.default = SVGO;

@@ -84,3 +84,3 @@ /* jshint quotmark: false */

.opt()
.name('disable').title('Disable plugin by name')
.name('disable').title('Disable plugin by name, "--disable={PLUGIN1,PLUGIN2}" for multiple plugins (*nix)')
.long('disable')

@@ -93,3 +93,3 @@ .arr()

.opt()
.name('enable').title('Enable plugin by name')
.name('enable').title('Enable plugin by name, "--enable={PLUGIN3,PLUGIN4}" for multiple plugins (*nix)')
.long('enable')

@@ -96,0 +96,0 @@ .arr()

@@ -30,3 +30,3 @@ 'use strict';

defaults = Object.assign({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));
defaults.plugins = preparePluginsArray(defaults.plugins);
defaults.plugins = preparePluginsArray(defaults.plugins || []);
defaults = extendConfig(defaults, config);

@@ -33,0 +33,0 @@ }

@@ -16,3 +16,25 @@ 'use strict';

/**
* Performs a deep clone of this object.
*
* @param parentNode the parentNode to assign to the cloned result
*/
CSSClassList.prototype.clone = function(parentNode) {
var node = this;
var nodeData = {};
Object.keys(node).forEach(function(key) {
if (key !== 'parentNode') {
nodeData[key] = node[key];
}
});
// Deep-clone node data.
nodeData = JSON.parse(JSON.stringify(nodeData));
var clone = new CSSClassList(parentNode);
Object.assign(clone, nodeData);
return clone;
};
CSSClassList.prototype.hasClass = function() {

@@ -19,0 +41,0 @@ this.classAttr = { // empty class attr

@@ -19,3 +19,25 @@ 'use strict';

/**
* Performs a deep clone of this object.
*
* @param parentNode the parentNode to assign to the cloned result
*/
CSSStyleDeclaration.prototype.clone = function(parentNode) {
var node = this;
var nodeData = {};
Object.keys(node).forEach(function(key) {
if (key !== 'parentNode') {
nodeData[key] = node[key];
}
});
// Deep-clone node data.
nodeData = JSON.parse(JSON.stringify(nodeData));
var clone = new CSSStyleDeclaration(parentNode);
Object.assign(clone, nodeData);
return clone;
};
CSSStyleDeclaration.prototype.hasStyle = function() {

@@ -109,4 +131,10 @@ this.addStyleHandler();

declarations.children.each(function(declaration) {
var styleDeclaration = csstools.csstreeToStyleDeclaration(declaration);
self.setProperty(styleDeclaration.name, styleDeclaration.value, styleDeclaration.priority);
try {
var styleDeclaration = csstools.csstreeToStyleDeclaration(declaration);
self.setProperty(styleDeclaration.name, styleDeclaration.value, styleDeclaration.priority);
} catch(styleError) {
if(styleError.message !== 'Unknown node type: undefined') {
self.parseError = styleError;
}
}
});

@@ -113,0 +141,0 @@ };

@@ -31,3 +31,3 @@ 'use strict';

Object.keys(node).forEach(function(key) {
if (key !== 'content') {
if (key !== 'class' && key !== 'style' && key !== 'content') {
nodeData[key] = node[key];

@@ -37,3 +37,3 @@ }

// Deep-clone node data
// Deep-clone node data.
nodeData = JSON.parse(JSON.stringify(nodeData));

@@ -46,2 +46,8 @@

if (node.class) {
clonedNode.class = node.class.clone(clonedNode);
}
if (node.style) {
clonedNode.style = node.style.clone(clonedNode);
}
if (node.content) {

@@ -249,3 +255,6 @@ clonedNode.content = node.content.map(function(childNode) {

if (Array.isArray(name)) name.forEach(this.removeAttr, this);
if (Array.isArray(name)) {
name.forEach(this.removeAttr, this);
return false;
}

@@ -252,0 +261,0 @@ if (!this.hasAttr(name)) return false;

@@ -18,5 +18,8 @@ 'use strict';

prefix += ';base64,';
str = prefix + new Buffer(str).toString('base64');
if (Buffer.from) {
str = prefix + Buffer.from(str).toString('base64');
} else {
str = prefix + new Buffer(str).toString('base64');
}
// URI encoded

@@ -23,0 +26,0 @@ } else if (type === 'enc') {

{
"name": "svgo",
"version": "1.0.5",
"version": "1.1.0",
"description": "Nodejs-based tool for optimizing SVG vector graphics files",

@@ -54,8 +54,8 @@ "keywords": [

"colors": "~1.1.2",
"css-select": "~1.3.0-rc0",
"css-select": "^2.0.0",
"css-select-base-adapter": "~0.1.0",
"css-tree": "1.0.0-alpha25",
"css-tree": "1.0.0-alpha.28",
"css-url-regex": "^1.1.0",
"csso": "^3.5.0",
"js-yaml": "~3.10.0",
"js-yaml": "^3.12.0",
"mkdirp": "~0.5.1",

@@ -72,2 +72,3 @@ "object.values": "^1.0.4",

"istanbul": "~0.4.5",
"jshint": "~2.9.5",
"mocha": "~4.0.1",

@@ -74,0 +75,0 @@ "mocha-istanbul": "~0.3.0",

'use strict';
// http://www.w3.org/TR/SVG/intro.html#Definitions
// http://www.w3.org/TR/SVG11/intro.html#Definitions
exports.elemsGroups = {

@@ -20,3 +20,3 @@ animation: ['animate', 'animateColor', 'animateMotion', 'animateTransform', 'set'],

// http://www.w3.org/TR/SVG/intro.html#Definitions
// http://www.w3.org/TR/SVG11/intro.html#Definitions
exports.attrsGroups = {

@@ -34,3 +34,2 @@ animationAddition: ['additive', 'accumulate'],

'baseline-shift',
'buffered-rendering',
'clip',

@@ -65,3 +64,2 @@ 'clip-path',

'image-rendering',
'kerning',
'letter-spacing',

@@ -75,6 +73,5 @@ 'lighting-color',

'overflow',
'paint-order',
'pointer-events',
'shape-rendering',
'solid-color',
'solid-opacity',
'stop-color',

@@ -90,14 +87,10 @@ 'stop-opacity',

'stroke-width',
'paint-order',
'text-anchor',
'text-decoration',
'text-overflow',
'white-space',
'text-rendering',
'transform',
'unicode-bidi',
'vector-effect',
'viewport-fill',
'viewport-fill-opacity',
'visibility',
'white-space',
'word-spacing',

@@ -121,4 +114,2 @@ 'writing-mode'

opacity: '1',
'solid-color': '#000',
'solid-opacity': '1',
'stop-color': '#000',

@@ -139,4 +130,2 @@ 'stop-opacity': '1',

'vector-effect': 'none',
'viewport-fill': 'none',
'viewport-fill-opacity': '1',
display: 'inline',

@@ -153,3 +142,2 @@ visibility: 'visible',

'image-rendering': 'auto',
'buffered-rendering': 'auto',
'font-style': 'normal',

@@ -179,3 +167,3 @@ 'font-variant': 'normal',

// http://www.w3.org/TR/SVG/eltindex.html
// http://www.w3.org/TR/SVG11/eltindex.html
exports.elems = {

@@ -2303,6 +2291,7 @@ a: {

'http://ns.adobe.com/GenericCustomNamespace/1.0/',
'http://ns.adobe.com/XPath/1.0/'
'http://ns.adobe.com/XPath/1.0/',
'http://schemas.microsoft.com/visio/2003/SVGExtensions/'
];
// http://www.w3.org/TR/SVG/linking.html#processingIRI
// http://www.w3.org/TR/SVG11/linking.html#processingIRI
exports.referencesProps = [

@@ -2321,3 +2310,3 @@ 'clip-path',

// http://www.w3.org/TR/SVG/propidx.html
// http://www.w3.org/TR/SVG11/propidx.html
exports.inheritableAttrs = [

@@ -2332,2 +2321,3 @@ 'clip-rule',

'direction',
'dominant-baseline',
'fill',

@@ -2347,3 +2337,2 @@ 'fill-opacity',

'image-rendering',
'kerning',
'letter-spacing',

@@ -2354,2 +2343,3 @@ 'marker',

'marker-start',
'paint-order',
'pointer-events',

@@ -2369,3 +2359,2 @@ 'shape-rendering',

'visibility',
'white-space',
'word-spacing',

@@ -2375,3 +2364,15 @@ 'writing-mode'

// http://www.w3.org/TR/SVG/single-page.html#types-ColorKeywords
exports.presentationNonInheritableGroupAttrs = [
'display',
'clip-path',
'filter',
'mask',
'opacity',
'text-decoration',
'transform',
'unicode-bidi',
'visibility'
];
// http://www.w3.org/TR/SVG11/single-page.html#types-ColorKeywords
exports.colorsNames = {

@@ -2563,5 +2564,5 @@ 'aliceblue': '#f0f8ff',

// http://www.w3.org/TR/SVG/single-page.html#types-DataTypeColor
// http://www.w3.org/TR/SVG11/single-page.html#types-DataTypeColor
exports.colorsProps = [
'color', 'fill', 'stroke', 'stop-color', 'flood-color', 'lighting-color'
];
/* global a2c */
'use strict';
var rNumber = String.raw`[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?\s*`,
rCommaWsp = String.raw`(?:\s,?\s*|,\s*)`,
rNumberCommaWsp = `(${rNumber})` + rCommaWsp,
rFlagCommaWsp = `([01])${rCommaWsp}?`,
rCoordinatePair = String.raw`(${rNumber})${rCommaWsp}?(${rNumber})`,
rArcSeq = (rNumberCommaWsp + '?').repeat(2) + rNumberCommaWsp + rFlagCommaWsp.repeat(2) + rCoordinatePair;
var regPathInstructions = /([MmLlHhVvCcSsQqTtAaZz])\s*/,
regPathData = /[-+]?(?:\d*\.\d+|\d+\.?)([eE][-+]?\d+)?/g,
regCoordinateSequence = new RegExp(rNumber, 'g'),
regArcArgumentSequence = new RegExp(rArcSeq, 'g'),
regNumericValues = /[-+]?(\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/,

@@ -56,7 +64,17 @@ transform2js = require('./_transforms').transform2js,

} else {
data = data.match(regPathData);
/* jshint boss: true */
if (instruction == 'A' || instruction == 'a') {
var newData = [];
for (var args; (args = regArcArgumentSequence.exec(data));) {
for (var i = 1; i < args.length; i++) {
newData.push(args[i]);
}
}
data = newData;
} else {
data = data.match(regCoordinateSequence);
}
if (!data) return;
data = data.map(Number);
// Subsequent moveto pairs of coordinates are threated as implicit lineto commands

@@ -212,12 +230,18 @@ // http://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands

if (elem.hasAttr('stroke-width')) {
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value.trim()
.replace(regNumericValues, function(num) { return removeLeadingZero(num * scale) });
} else {
elem.addAttr({
name: 'stroke-width',
prefix: '',
local: 'stroke-width',
value: strokeWidth.replace(regNumericValues, function(num) { return removeLeadingZero(num * scale) })
});
if (!elem.hasAttr('vector-effect') || elem.attr('vector-effect').value !== 'non-scaling-stroke') {
if (elem.hasAttr('stroke-width')) {
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value.trim()
.replace(regNumericValues, function(num) {
return removeLeadingZero(num * scale);
});
} else {
elem.addAttr({
name: 'stroke-width',
prefix: '',
local: 'stroke-width',
value: strokeWidth.replace(regNumericValues, function(num) {
return removeLeadingZero(num * scale);
})
});
}
}

@@ -224,0 +248,0 @@ }

@@ -118,3 +118,3 @@ 'use strict';

* Decompose matrix into simple transforms. See
* http://www.maths-informatique-jeux.com/blog/frederic/?post/2013/12/01/Decomposition-of-2D-transform-matrices
* http://frederic-wang.fr/decomposition-of-2d-transform-matrices.html
*

@@ -128,7 +128,7 @@ * @param {Object} data matrix transform object

transforms = [],
sx = +Math.sqrt(data[0] * data[0] + data[1] * data[1]).toFixed(params.transformPrecision),
sx = +Math.hypot(data[0], data[1]).toFixed(params.transformPrecision),
sy = +((data[0] * data[3] - data[1] * data[2]) / sx).toFixed(params.transformPrecision),
colsSum = data[0] * data[2] + data[1] * data[3],
rowsSum = data[0] * data[1] + data[2] * data[3],
scaleBefore = rowsSum || +(sx == sy);
scaleBefore = rowsSum != 0 || sx == sy;

@@ -154,7 +154,7 @@ // [..., ..., ..., ..., tx, ty] → translate(tx, ty)

if (!scaleBefore) {
sx = (data[0] < 0 ? -1 : 1) * Math.sqrt(data[0] * data[0] + data[2] * data[2]);
sy = (data[3] < 0 ? -1 : 1) * Math.sqrt(data[1] * data[1] + data[3] * data[3]);
sx = (data[0] < 0 ? -1 : 1) * Math.hypot(data[0], data[2]);
sy = (data[3] < 0 ? -1 : 1) * Math.hypot(data[1], data[3]);
transforms.push({ name: 'scale', data: [sx, sy] });
}
var rotate = [mth.acos(data[0] / sx, floatPrecision) * (data[1] * sy < 0 ? -1 : 1)];
var rotate = [mth.acos(data[0] / sx, floatPrecision) * ((scaleBefore ? 1 : sy) * data[1] < 0 ? -1 : 1)];

@@ -266,6 +266,3 @@ if (rotate[0]) transforms.push({ name: 'rotate', data: rotate });

squareSum = m[0] * m[0] + m[1] * m[1] + lastCol,
root = Math.sqrt(
(Math.pow(m[0] - m[3], 2) + Math.pow(m[1] + m[2], 2)) *
(Math.pow(m[0] + m[3], 2) + Math.pow(m[1] - m[2], 2))
);
root = Math.hypot(m[0] - m[3], m[1] + m[2]) * Math.hypot(m[0] + m[3], m[1] - m[2]);

@@ -286,3 +283,3 @@ if (!root) { // circle

arc[2] = ((major ? term2 < 0 : term1 > 0) ? -1 : 1) *
Math.acos((major ? term1 : term2) / Math.sqrt(term1 * term1 + term2 * term2)) * 180 / Math.PI;
Math.acos((major ? term1 : term2) / Math.hypot(term1, term2)) * 180 / Math.PI;
}

@@ -289,0 +286,0 @@

@@ -99,4 +99,3 @@ 'use strict';

// if attribute value matches regNumericValues
if(match){
if (match) {
// round it to the fixed precision

@@ -126,9 +125,8 @@ num = +(+match[1]).toFixed(params.floatPrecision),

roundedListArr.push(num+units);
}
// if attribute value is "new"(only enable-background).
else if(matchNew){
else if (matchNew) {
roundedListArr.push('new');
} else {
roundedListArr.push(elem);
}

@@ -135,0 +133,0 @@

@@ -43,3 +43,3 @@ 'use strict';

if (item.hasAttr('viewBox')) {
var nums = item.attr('viewBox').value.split(/[ ,]/g);
var nums = item.attr('viewBox').value.split(/\s,?\s*|,\s*/g);
item.attr('viewBox').value = nums.map(function(value) {

@@ -52,2 +52,5 @@ var num = +value;

item.eachAttr(function(attr) {
// The `version` attribute is a text string and cannot be rounded
if (attr.name === 'version') { return }
var match = attr.value.match(regNumericValues);

@@ -54,0 +57,0 @@

@@ -45,3 +45,3 @@ 'use strict';

// non-empty elements
if (item.isElem() && (!item.isElem('switch') || isFeaturedSwitch(item)) && !item.isEmpty()) {
if (item.isElem() && !item.isElem('switch') && !item.isEmpty()) {
item.content.forEach(function(g, i) {

@@ -54,3 +54,3 @@ // non-empty groups

if (inner.isElem() && !inner.hasAttr('id') &&
if (inner.isElem() && !inner.hasAttr('id') && !g.hasAttr('filter') &&
!(g.hasAttr('class') && inner.hasAttr('class')) && (

@@ -68,2 +68,4 @@ !g.hasAttr('clip-path') && !g.hasAttr('mask') ||

inner.attr(attr.name).value = attr.value + ' ' + inner.attr(attr.name).value;
} else if (inner.hasAttr(attr.name, 'inherit')) {
inner.attr(attr.name).value = attr.value;
} else if (

@@ -85,4 +87,2 @@ attrsInheritable.indexOf(attr.name) < 0 &&

}
} else if (isFeaturedSwitch(g)) {
item.spliceContent(i, 1, g.content);
}

@@ -92,7 +92,1 @@ });

};
function isFeaturedSwitch(elem) {
return elem.isElem('switch') && !elem.isEmpty() && !elem.content.some(child =>
child.hasAttr('systemLanguage') || child.hasAttr('requiredFeatures') || child.hasAttr('requiredExtensions')
);
}

@@ -25,3 +25,4 @@ 'use strict';

leadingZero: true,
negativeExtraSpace: true
negativeExtraSpace: true,
forceAbsolutePath: false
};

@@ -39,3 +40,4 @@

arcTolerance,
hasMarkerMid;
hasMarkerMid,
hasStrokeLinecap;

@@ -71,2 +73,6 @@ /**

var stroke = item.computedAttr('stroke'),
strokeLinecap = item.computedAttr('stroke');
hasStrokeLinecap = stroke && stroke != 'none' && strokeLinecap && strokeLinecap != 'butt';
var data = path2js(item);

@@ -589,3 +595,3 @@

// remove useless non-first path segments
if (params.removeUseless) {
if (params.removeUseless && !hasStrokeLinecap) {

@@ -678,3 +684,3 @@ // l 0,0 / h 0 / v 0 / q 0,0 0,0 / t 0,0 / c 0,0 0,0 0,0 / s 0,0 0,0

// Convert to absolute coordinates if it's shorter.
// Convert to absolute coordinates if it's shorter or forceAbsolutePath is true.
// v-20 -> V0

@@ -684,2 +690,3 @@ // Don't convert if it fits following previous instruction.

if (
params.forceAbsolutePath || (
absoluteDataStr.length < relativeDataStr.length &&

@@ -692,3 +699,3 @@ !(

(data[0] < 0 || /^0\./.test(data[0]) && prev.data[prev.data.length - 1] % 1)
)
))
) {

@@ -850,3 +857,3 @@ item.instruction = instruction.toUpperCase();

function getDistance(point1, point2) {
return Math.sqrt(Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));
return Math.hypot(point1[0] - point2[0], point1[1] - point2[1]);
}

@@ -896,3 +903,4 @@

if (center && [1/4, 3/4].every(function(point) {
if (center && radius < 1e15 &&
[1/4, 3/4].every(function(point) {
return Math.abs(getDistance(getCubicBezierPoint(curve, point), center) - radius) <= tolerance;

@@ -899,0 +907,0 @@ }))

@@ -10,2 +10,6 @@ /* jshint quotmark: false */

exports.params = {
keepImportant: false
};
var stylingProps = require('./_collections').attrsGroups.presentation,

@@ -23,3 +27,3 @@ rEscape = '\\\\(?:[0-9a-f]{1,6}\\s?|\\r\\n|.)', // Like \" or \2051. Code points consume one space.

// The value. It can have strings and parentheses (see above). Fallbacks to anything in case of unexpected input.
rValue = '\\s*(' + g('[^\'"();\\\\]+?', rEscape, rSingleQuotes, rQuotes, rParenthesis, '[^;]*?') + '*?' + ')',
rValue = '\\s*(' + g('[^!\'"();\\\\]+?', rEscape, rSingleQuotes, rQuotes, rParenthesis, '[^;]*?') + '*?' + ')',

@@ -29,4 +33,7 @@ // End of declaration. Spaces outside of capturing groups help to do natural trimming.

// Important rule
rImportant = '(\\s*!important(?![-(\w]))?',
// Final RegExp to parse CSS declarations.
regDeclarationBlock = new RegExp(rAttr + ':' + rValue + rDeclEnd, 'ig'),
regDeclarationBlock = new RegExp(rAttr + ':' + rValue + rImportant + rDeclEnd, 'ig'),

@@ -54,3 +61,3 @@ // Comments expression. Honors escape sequences and strings.

*/
exports.fn = function(item) {
exports.fn = function(item, params) {
/* jshint boss: true */

@@ -72,3 +79,5 @@

for (var rule; rule = regDeclarationBlock.exec(styleValue);) {
styles.push([rule[1], rule[2]]);
if (!params.keepImportant || !rule[3]) {
styles.push([rule[1], rule[2]]);
}
}

@@ -75,0 +84,0 @@

@@ -106,3 +106,3 @@ 'use strict';

for (selector of sortedSelectors) {
var selectorStr = csstree.translate(selector.item.data),
var selectorStr = csstree.generate(selector.item.data),
selectedEls = null;

@@ -147,3 +147,3 @@

// merge declarations
csstree.walkDeclarations(selector.rule, function(styleCsstreeDeclaration) {
csstree.walk(selector.rule, {visit: 'Declaration', enter: function(styleCsstreeDeclaration) {

@@ -160,3 +160,3 @@ // existing inline styles have higher priority

selectedEl.style.setProperty(styleDeclaration.name, styleDeclaration.value, styleDeclaration.priority);
});
}});
}

@@ -208,3 +208,3 @@

for (var style of styles) {
csstree.walkRules(style.cssAst, function(node, item, list) {
csstree.walk(style.cssAst, {visit: 'Rule', enter: function(node, item, list) {
// clean up <style/> atrules without any rulesets left

@@ -224,3 +224,3 @@ if (node.type === 'Atrule' &&

}
});
}});

@@ -245,3 +245,3 @@

// update existing, left over <style>s
cssTools.setCssStr(style.styleEl, csstree.translate(style.cssAst));
cssTools.setCssStr(style.styleEl, csstree.generate(style.cssAst));
}

@@ -248,0 +248,0 @@

@@ -64,4 +64,4 @@ 'use strict';

// prefixes a normal attribute value
var addPrefixToAttr = function(attr) {
// prefixes a class attribute value
var addPrefixToClassAttr = function(attr) {
if (!attrNotEmpty(attr)) {

@@ -71,3 +71,3 @@ return;

attr.value = addPrefix(attr.value);
attr.value = attr.value.split(/\s+/).map(addPrefix).join(' ');
};

@@ -81,2 +81,11 @@

attr.value = addPrefix(attr.value);
};
// prefixes a href attribute value
var addPrefixToHrefAttr = function(attr) {
if (!attrNotEmpty(attr)) {
return;
}
var idPrefixed = prefixId(attr.value);

@@ -129,2 +138,4 @@ if (!idPrefixed) {

}
} else if (opts.prefix === false) {
prefix = false;
} else if (extra && extra.path && extra.path.length > 0) {

@@ -138,2 +149,5 @@ var filename = path.basename(extra.path);

addPrefix = function(name) {
if(prefix === false){
return escapeIdentifierName(name);
}
return escapeIdentifierName(prefix + opts.delim + name);

@@ -188,3 +202,3 @@ };

// update <style>s
node.content[0].text = csstree.translate(cssAst);
node.content[0].text = csstree.generate(cssAst);
return node;

@@ -201,10 +215,12 @@ }

// ID
addPrefixToAttr(node.attrs.id);
addPrefixToIdAttr(node.attrs.id);
// Class
addPrefixToAttr(node.attrs.class);
addPrefixToClassAttr(node.attrs.class);
// href
addPrefixToIdAttr(node.attrs.href);
addPrefixToHrefAttr(node.attrs.href);
// (xlink:)href (deprecated, must be still supported)
addPrefixToIdAttr(node.attrs['xlink:href']);
addPrefixToHrefAttr(node.attrs['xlink:href']);

@@ -211,0 +227,0 @@ // referenceable properties

@@ -10,2 +10,3 @@ 'use strict';

exports.params = {
isHidden: true,
displayNone: true,

@@ -48,5 +49,11 @@ opacity0: true,

*/
exports.fn = function(item, params) {
exports.fn = function (item, params) {
if (item.elem) {
// Removes hidden elements
// https://www.w3schools.com/cssref/pr_class_visibility.asp
if (
params.isHidden &&
item.hasAttr('visibility', 'hidden')
) return false;

@@ -53,0 +60,0 @@ // display="none"

@@ -11,3 +11,3 @@ 'use strict';

attrsGroups = require('./_collections').attrsGroups,
excludedAttrs = ['display', 'opacity'];
applyGroups = require('./_collections').presentationNonInheritableGroupAttrs;

@@ -29,7 +29,4 @@ /**

~attrsGroups.presentation.indexOf(attr.name) &&
~attrsGroups.graphicalEvent.indexOf(attr.name) &&
~attrsGroups.core.indexOf(attr.name) &&
~attrsGroups.conditionalProcessing.indexOf(attr.name) &&
!~excludedAttrs.indexOf(attr.name) &&
!~inheritableAttrs.indexOf(attr.name)
!~inheritableAttrs.indexOf(attr.name) &&
!~applyGroups.indexOf(attr.name)
) {

@@ -36,0 +33,0 @@ item.removeAttr(attr.name);

@@ -15,3 +15,4 @@ 'use strict';

keepDataAttrs: true,
keepAriaAttrs: true
keepAriaAttrs: true,
keepRoleAttr: false
};

@@ -24,3 +25,4 @@

attrsGroupsDefaults = collections.attrsGroupsDefaults,
attrsInheritable = collections.inheritableAttrs;
attrsInheritable = collections.inheritableAttrs,
applyGroups = collections.presentationNonInheritableGroupAttrs;

@@ -112,3 +114,4 @@ // collect and extend all references

(!params.keepDataAttrs || attr.name.indexOf('data-') != 0) &&
(!params.keepAriaAttrs || attr.name.indexOf('aria-') != 0)
(!params.keepAriaAttrs || attr.name.indexOf('aria-') != 0) &&
(!params.keepRoleAttr || attr.name != 'role')
) {

@@ -124,2 +127,3 @@ if (

params.defaultAttrs &&
!item.hasAttr('id') &&
elems[elem].defaults &&

@@ -134,3 +138,4 @@ elems[elem].defaults[attr.name] === attr.value && (

params.uselessOverrides &&
attr.name !== 'transform' &&
!item.hasAttr('id') &&
applyGroups.indexOf(attr.name) < 0 &&
attrsInheritable.indexOf(attr.name) > -1 &&

@@ -137,0 +142,0 @@ item.parentNode.computedAttr(attr.name, attr.value)

@@ -33,3 +33,4 @@ 'use strict';

sorted = {},
orderlen = params.order.length + 1;
orderlen = params.order.length + 1,
xmlnsOrder = params.xmlnsOrder || 'front';

@@ -45,6 +46,8 @@ if (item.elem) {

// xmlns attributes implicitly have the prefix xmlns
if (a.prefix == 'xmlns')
return -1;
if (b.prefix == 'xmlns')
return 1;
if (xmlnsOrder == 'front') {
if (a.prefix == 'xmlns')
return -1;
if (b.prefix == 'xmlns')
return 1;
}
return a.prefix < b.prefix ? -1 : 1;

@@ -51,0 +54,0 @@ }

@@ -6,3 +6,3 @@ **english** | [русский](https://github.com/svg/svgo/blob/master/README.ru.md)

## SVGO [![NPM version](https://badge.fury.io/js/svgo.svg)](https://npmjs.org/package/svgo) [![Dependency Status](https://gemnasium.com/svg/svgo.svg)](https://gemnasium.com/svg/svgo) [![Build Status](https://secure.travis-ci.org/svg/svgo.svg)](https://travis-ci.org/svg/svgo) [![Coverage Status](https://img.shields.io/coveralls/svg/svgo.svg)](https://coveralls.io/r/svg/svgo?branch=master)
## SVGO [![NPM version](https://badge.fury.io/js/svgo.svg)](https://npmjs.org/package/svgo) [![Build Status](https://secure.travis-ci.org/svg/svgo.svg)](https://travis-ci.org/svg/svgo) [![Coverage Status](https://img.shields.io/coveralls/svg/svgo.svg)](https://coveralls.io/r/svg/svgo?branch=master)

@@ -14,3 +14,3 @@ **SVG O**ptimizer is a Nodejs-based tool for optimizing SVG vector graphics files.

SVG files, especially exported from various editors, usually contain a lot of redundant and useless information such as editor metadata, comments, hidden elements, default or non-optimal values and other stuff that can be safely removed or converted without affecting SVG rendering result.
SVG files, especially those exported from various editors, usually contain a lot of redundant and useless information. This can include editor metadata, comments, hidden elements, default or non-optimal values and other stuff that can be safely removed or converted without affecting the SVG rendering result.

@@ -26,2 +26,3 @@ ## What it can do

| [cleanupAttrs](https://github.com/svg/svgo/blob/master/plugins/cleanupAttrs.js) | cleanup attributes from newlines, trailing, and repeating spaces |
| [inlineStyles](https://github.com/svg/svgo/blob/master/plugins/inlineStyles.js) | move and merge styles from `<style>` elements to element `style` attributes |
| [removeDoctype](https://github.com/svg/svgo/blob/master/plugins/removeDoctype.js) | remove doctype declaration |

@@ -95,4 +96,4 @@ | [removeXMLProcInst](https://github.com/svg/svgo/blob/master/plugins/removeXMLProcInst.js) | remove XML processing instructions |

--config=CONFIG : Config file or JSON string to extend or replace default
--disable=PLUGIN : Disable plugin by name, "--disable={PLUGIN1,PLUGIN2}" for multiple plugins
--enable=PLUGIN : Enable plugin by name, "--enable={PLUGIN3,PLUGIN4}" for multiple plugins
--disable=PLUGIN : Disable plugin by name, "--disable={PLUGIN1,PLUGIN2}" for multiple plugins (*nix)
--enable=PLUGIN : Enable plugin by name, "--enable={PLUGIN3,PLUGIN4}" for multiple plugins (*nix)
--datauri=DATAURI : Output as Data URI string (base64, URI encoded or unencoded)

@@ -183,3 +184,3 @@ --multipass : Enable multipass

* as a web app - [SVGOMG](https://jakearchibald.github.io/svgomg/)
* as a web app – [SVGOMG](https://jakearchibald.github.io/svgomg/)
* as a Nodejs module – [examples](https://github.com/svg/svgo/tree/master/examples)

@@ -192,4 +193,7 @@ * as a Grunt task – [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)

* as a Telegram Bot – [svgo_bot](https://github.com/maksugr/svgo_bot)
* as a PostCSS plugin - [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
* as an Inkscape plugin - [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
* as a PostCSS plugin – [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
* as an Inkscape plugin – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
* as a Sketch plugin - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
* as macOS app - [Image Shrinker](https://image-shrinker.com)
* as a Rollup plugin - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)

@@ -196,0 +200,0 @@ ## License and Copyright

@@ -6,3 +6,3 @@ [english](https://github.com/svg/svgo/blob/master/README.md) | **русский**

## SVGO [![NPM version](https://badge.fury.io/js/svgo.svg)](https://npmjs.org/package/svgo) [![Dependency Status](https://gemnasium.com/svg/svgo.svg)](https://gemnasium.com/svg/svgo) [![Build Status](https://secure.travis-ci.org/svg/svgo.svg)](https://travis-ci.org/svg/svgo) [![Coverage Status](https://img.shields.io/coveralls/svg/svgo.svg)](https://coveralls.io/r/svg/svgo?branch=master)
## SVGO [![NPM version](https://badge.fury.io/js/svgo.svg)](https://npmjs.org/package/svgo) [![Build Status](https://secure.travis-ci.org/svg/svgo.svg)](https://travis-ci.org/svg/svgo) [![Coverage Status](https://img.shields.io/coveralls/svg/svgo.svg)](https://coveralls.io/r/svg/svgo?branch=master)

@@ -14,3 +14,3 @@ **SVG** **O**ptimizer – это инструмент для оптимизации векторной графики в формате SVG, написанный на Node.js.

SVG-файлы, особенно – экспортированные из различных редакторов, содержат много избыточной и бесполезной информации, комментариев, скрытых элементов, неоптимальные или стандартные значения и другой мусор, удаление которого безопасно и не влияет на конечный результат отрисовки.
SVG-файлы, особенно экспортированные из редакторов, содержат много избыточной и бесполезной информации, комментариев, скрытых элементов, неоптимальные или стандартные значения и другой мусор, удаление которого безопасно и не влияет на конечный вид изображения.

@@ -21,3 +21,3 @@ ## Возможности

Сегодня у нас есть:
Что у нас есть:

@@ -27,2 +27,3 @@ | Plugin | Description |

| [cleanupAttrs](https://github.com/svg/svgo/blob/master/plugins/cleanupAttrs.js) | удаление переносов строк и лишних пробелов |
| [inlineStyles](https://github.com/svg/svgo/blob/master/plugins/inlineStyles.js) | перенос стилей из элементов `<style>` в атрибуты `style` |
| [removeDoctype](https://github.com/svg/svgo/blob/master/plugins/removeDoctype.js) | удаление doctype |

@@ -70,3 +71,3 @@ | [removeXMLProcInst](https://github.com/svg/svgo/blob/master/plugins/removeXMLProcInst.js) | удаление XML-инструкций |

Хотите узнать, как это работает и как написать свой плагин? [Конечно же, да!](https://github.com/svg/svgo/blob/master/docs/how-it-works/ru.md).
Хотите узнать принципы работы и как написать свой плагин? [Конечно же, да!](https://github.com/svg/svgo/blob/master/docs/how-it-works/ru.md)

@@ -193,2 +194,6 @@

* как плагин PostCSS - [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
* как плагин для Inkscape – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
* как плагин для Sketch - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
* в виде приложения macOS - [Image Shrinker](https://image-shrinker.com)
* как плагин для Rollup - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)

@@ -195,0 +200,0 @@ ## Лицензия и копирайты

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc