Socket
Socket
Sign inDemoInstall

svgo

Package Overview
Dependencies
5
Maintainers
2
Versions
102
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.4.5 to 0.5.0

plugins/removeDesc.js

18

CHANGELOG.md

@@ -0,1 +1,19 @@

### [ [>](https://github.com/svg/svgo/tree/v0.4.5) ] 0.5.0 / 05.11.2014
* added ``--multipass`` command line option which repeatedly applies optimizations like collapsing groups (by @dfilatov)
* exposed JSAPI as a factory method (by @mistakster)
* added removeDesc plugin (by @dwabyick), disabled by default
* [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill) plugin is disabled by default since it's unable to check inherited properties
* transformations now apply to paths with arcs in [plugins/convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js)
* a lot of bug fixes mostly related to transformations
### [ [>](https://github.com/svg/svgo/tree/v0.4.5) ] 0.4.5 / 02.08.2014
* significally improved plugin [plugins/convertPathData](https://github.com/svg/svgo/blob/master/plugins/convertPathData.js):
- Now data is being written relative or absolute whichever is shorter. You can turn it off by setting ``utilizeAbsolute`` to ``false``.
- Smarter rounding: values like 2.499 now rounds to 2.5. Rounding now takes in account accumulutive error meaning that points will not be misplaced due to rounding more than it neccessary.
- Fixed couple bugs.
* ``--output`` option now can be a folder along with ``--folder``, thanks to @mako-taco.
* [plugins/cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) now have ``prefix`` option in case you want to combine multiple svg later (by @DanielMazurkiewicz).
* Quotes now being escaped in attributes (by @ditesh).
* Minor bugfixes.
### [ [>](https://github.com/svg/svgo/tree/v0.4.4) ] 0.4.4 / 14.01.2014

@@ -2,0 +20,0 @@ * new plugin [plugins/removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) (disabled by default, close [#159](https://github.com/svg/svgo/issues/159))

31

lib/svgo.js

@@ -6,7 +6,7 @@ 'use strict';

*
* @see http://deepsweet.github.com/svgo/
* @see https://github.com/svg/svgo
*
* @author Kir Belevich <kir@soulshine.in> (https://github.com/deepsweet)
* @copyright © 2012 Kir Belevich
* @license MIT https://raw.github.com/deepsweet/svgo/master/LICENSE
* @license MIT https://raw.githubusercontent.com/svg/svgo/master/LICENSE
*/

@@ -17,2 +17,3 @@

PLUGINS = require('./svgo/plugins'),
JSAPI = require('./svgo/jsAPI.js'),
JS2SVG = require('./svgo/js2svg');

@@ -37,8 +38,30 @@

svgjs = PLUGINS(svgjs, config.plugins);
var svg = { data : null },
maxIterationCount = config.multipass ? 10 : 1,
counter = 0,
prevResult;
callback(JS2SVG(svgjs, config.js2svg));
do {
prevResult = svg;
svgjs = PLUGINS(svgjs, config.plugins);
svg = JS2SVG(svgjs, config.js2svg);
} while(++counter < maxIterationCount && prevResult.data !== svg.data);
callback(svg);
});
};
/**
* The factory that creates a content item with the helper methods.
*
* @param {Object} data which passed to jsAPI constructor
* @returns {JSAPI} content item
*/
SVGO.prototype.createContentItem = function(data) {
return new JSAPI(data);
};
'use strict';
require('colors');
require('js-yaml');

@@ -10,2 +9,3 @@ var FS = require('fs'),

SVGO = require('../svgo'),
YAML = require('js-yaml'),
PKG = require('../../package.json'),

@@ -90,2 +90,7 @@ encodeSVGDatauri = require('./tools').encodeSVGDatauri,

.opt()
.name('multipass').title('Enable multipass')
.long('multipass')
.flag()
.end()
.opt()
.name('pretty').title('Make SVG pretty printed')

@@ -105,3 +110,3 @@ .long('pretty')

output = args && args.output ? args.output : opts.output,
config,
config = {},
configFull;

@@ -127,3 +132,7 @@

} else {
config = require(PATH.resolve(opts.config));
try {
config = require(PATH.resolve(opts.config));
} catch (e) {
config = YAML.safeLoad(FS.readFileSync(PATH.resolve(opts.config), 'utf8'));
}
}

@@ -143,2 +152,10 @@

// --multipass
if (opts.multipass) {
config = config || {};
config.multipass = true;
}
// --pretty

@@ -434,3 +451,3 @@ if (opts.pretty) {

else if (++i < files.length) {
optimizeFile(files[i]);
optimizeFile(files[i]);
}

@@ -437,0 +454,0 @@

8

lib/svgo/config.js
'use strict';
require('js-yaml');
var FS = require('fs');
var yaml = require('js-yaml');

@@ -27,5 +28,7 @@ var EXTEND = require('whet.extend');

defaults.multipass = config.multipass;
} else {
defaults = EXTEND({}, require('../../.svgo.yml'));
defaults = EXTEND({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));

@@ -36,2 +39,3 @@ defaults.plugins = preparePluginsArray(defaults.plugins);

defaults = extendConfig(defaults, config);
defaults.multipass = config.multipass;
}

@@ -38,0 +42,0 @@

@@ -140,1 +140,20 @@ 'use strict';

};
/**
* Tests whether some attribute passes the test.
*
* @param {Function} callback callback
* @param {Object} [context] callback context
* @return {Boolean} false if there are no any attributes
*/
JSAPI.prototype.someAttr = function(callback, context) {
if (!this.hasAttr()) return false;
for (var name in this.attrs) {
if (callback.call(context, this.attrs[name])) return true;
}
return false;
};
{
"name": "svgo",
"version": "0.4.5",
"version": "0.5.0",
"description": "Nodejs-based tool for optimizing SVG vector graphics files",

@@ -43,13 +43,13 @@ "keywords": [ "svgo", "svg", "optimize", "minify" ],

"sax": "~0.6.0",
"coa": "~0.4.0",
"js-yaml": "~2.1.0",
"colors": "~0.6.0",
"coa": "~0.4.1",
"js-yaml": "~3.2.2",
"colors": "~1.0.3",
"whet.extend": "~0.9.9"
},
"devDependencies": {
"mocha": "~1.14.0",
"should": "~2.1.0",
"istanbul": "~0.2.0",
"mocha": "~2.0.1",
"should": "~4.1.0",
"istanbul": "~0.3.2",
"mocha-istanbul": "~0.2.0",
"coveralls": "~2.11.1"
"coveralls": "~2.11.2"
},

@@ -56,0 +56,0 @@ "engines": {

@@ -5,5 +5,7 @@ 'use strict';

regPathData = /[\-+]?\d*\.?\d+([eE][\-+]?\d+)?/g,
regValue = /[+-]?\d+(?:e[+-]?\d+)?|[+-]?\d*\.\d+(?:e[+-]?\d+)?/i,
transform2js = require('./_transforms').transform2js,
transformsMultiply = require('./_transforms').transformsMultiply,
cleanupOutData = require('../lib/svgo/tools').cleanupOutData;
cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
removeLeadingZero = require('../lib/svgo/tools').removeLeadingZero;

@@ -189,11 +191,11 @@ /**

exports.applyTransforms = function(elem, path, applyTransformsStroked, floatPrecision) {
// if there are no 'stroke' attr and 'a' segments
if (
!elem.hasAttr('transform') ||
!path.every(function(i) { return i.instruction !== 'a'; })
) {
return path;
}
// if there are no 'stroke' attr and references to other objects such as
// gradiends or clip-path which are also subjects to transform.
if (!elem.hasAttr('transform') ||
elem.someAttr(function(attr) { return ~attr.value.indexOf('url(') }))
return path;
var matrix = transformsMultiply(transform2js(elem.attr('transform').value)),
newPoint, sx, sy, strokeWidth;
splittedMatrix = matrix.splitted || splitMatrix(matrix.data),
newPoint, sx, sy, strokeWidth;

@@ -220,3 +222,4 @@ if (elem.hasAttr('stroke') || elem.hasAttr('stroke-width')){

if (elem.hasAttr('stroke-width')){
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value * sx;
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value
.replace(regValue, function(num) { return removeLeadingZero(num * sx) });
} else {

@@ -233,2 +236,28 @@ elem.addAttr({

// If an 'a' command can't be transformed directly, convert path to curves.
if (!splittedMatrix.isSimple && path.some(function(i) { return i.instruction == 'a' })) {
var prev;
path = path.reduce(function(newPath, item){
if (item.instruction == 'a') {
var curves = a2c.apply(0, [0, 0].concat(item.data)),
curveData;
while ((curveData = curves.splice(0,6)).length) {
item = {
instruction: 'c',
data: curveData,
base: prev.coords
};
item.coords = [item.base[0] + item.data[4], item.base[1] + item.data[5]];
prev = item;
newPath.push(item);
}
} else {
newPath.push(item);
if (prev) item.base = prev.coords;
prev = item;
}
return newPath;
}, []);
}
path.forEach(function(pathItem) {

@@ -270,6 +299,18 @@

for (var i = 0; i < pathItem.data.length; i += 2) {
newPoint = transformPoint(matrix.data, pathItem.data[i], pathItem.data[i + 1]);
pathItem.data[i] = newPoint[0];
pathItem.data[i + 1] = newPoint[1];
if (pathItem.instruction == 'a') {
pathItem.data[0] *= splittedMatrix.scalex;
pathItem.data[1] *= splittedMatrix.scaley;
pathItem.data[2] += splittedMatrix.rotate;
newPoint = transformPoint(matrix.data, pathItem.data[5], pathItem.data[6]);
pathItem.data[5] = newPoint[0];
pathItem.data[6] = newPoint[1];
} else {
for (var i = 0; i < pathItem.data.length; i += 2) {
newPoint = transformPoint(matrix.data, pathItem.data[i], pathItem.data[i + 1]);
pathItem.data[i] = newPoint[0];
pathItem.data[i + 1] = newPoint[1];
}
}

@@ -526,1 +567,149 @@

};
/* Based on code from Snap.svg (Apache 2 license). http://snapsvg.io/
* Thanks to Dmitry Baranovskiy for his great work!
*/
function norm(a) {
return a[0] * a[0] + a[1] * a[1];
}
function normalize(a) {
var mag = Math.sqrt(norm(a));
if (a[0]) a[0] /= mag;
if (a[1]) a[1] /= mag;
}
function deg(rad) {
return rad * 180 / Math.PI % 360;
}
function determinant(matrix) {
return matrix[0] * matrix[3] - matrix[1] * matrix[2];
};
/* Splits matrix into primitive transformations
= (object) in format:
o dx (number) translation by x
o dy (number) translation by y
o scalex (number) scale by x
o scaley (number) scale by y
o shear (number) shear
o rotate (number) rotation in deg
o isSimple (boolean) could it be represented via simple transformations
*/
function splitMatrix(matrix) {
var out = {};
// translation
out.dx = matrix[4];
out.dy = matrix[5];
// scale and shear
var row = [[matrix[0] , matrix[2] ], [matrix[1] , matrix[3]]];
out.scalex = Math.sqrt(norm(row[0]));
normalize(row[0]);
out.shear = row[0][0] * row[1][0] + row[0][1] * row[1][1];
row[1] = [row[1][0] - row[0][0] * out.shear, row[1][1] - row[0][1] * out.shear];
out.scaley = Math.sqrt(norm(row[1]));
normalize(row[1]);
out.shear /= out.scaley;
if (determinant(matrix) < 0) {
out.scalex = -out.scalex;
}
// rotation
var sin = -row[0][1],
cos = row[1][1];
if (cos < 0) {
out.rotate = deg(Math.acos(cos));
if (sin < 0) {
out.rotate = 360 - out.rotate;
}
} else {
out.rotate = deg(Math.asin(sin));
}
out.isSimple = !+out.shear.toFixed(9) && (out.scalex.toFixed(9) == out.scaley.toFixed(9) || !out.rotate);
return out;
};
function a2c(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2, recursive) {
// for more information of where this Math came from visit:
// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
var _120 = Math.PI * 120 / 180,
rad = Math.PI / 180 * (+angle || 0),
res = [],
rotateX = function(x, y, rad) { return x * Math.cos(rad) - y * Math.sin(rad) },
rotateY = function(x, y, rad) { return x * Math.sin(rad) + y * Math.cos(rad) };
if (!recursive) {
x1 = rotateX(x1, y1, -rad);
y1 = rotateY(x1, y1, -rad);
x2 = rotateX(x2, y2, -rad);
y2 = rotateY(x2, y2, -rad);
var cos = Math.cos(Math.PI / 180 * angle),
sin = Math.sin(Math.PI / 180 * angle),
x = (x1 - x2) / 2,
y = (y1 - y2) / 2;
var h = (x * x) / (rx * rx) + (y * y) / (ry * ry);
if (h > 1) {
h = Math.sqrt(h);
rx = h * rx;
ry = h * ry;
}
var rx2 = rx * rx,
ry2 = ry * ry,
k = (large_arc_flag == sweep_flag ? -1 : 1) *
Math.sqrt(Math.abs((rx2 * ry2 - rx2 * y * y - ry2 * x * x) / (rx2 * y * y + ry2 * x * x))),
cx = k * rx * y / ry + (x1 + x2) / 2,
cy = k * -ry * x / rx + (y1 + y2) / 2,
f1 = Math.asin(((y1 - cy) / ry).toFixed(9)),
f2 = Math.asin(((y2 - cy) / ry).toFixed(9));
f1 = x1 < cx ? Math.PI - f1 : f1;
f2 = x2 < cx ? Math.PI - f2 : f2;
f1 < 0 && (f1 = Math.PI * 2 + f1);
f2 < 0 && (f2 = Math.PI * 2 + f2);
if (sweep_flag && f1 > f2) {
f1 = f1 - Math.PI * 2;
}
if (!sweep_flag && f2 > f1) {
f2 = f2 - Math.PI * 2;
}
} else {
f1 = recursive[0];
f2 = recursive[1];
cx = recursive[2];
cy = recursive[3];
}
var df = f2 - f1;
if (Math.abs(df) > _120) {
var f2old = f2,
x2old = x2,
y2old = y2;
f2 = f1 + _120 * (sweep_flag && f2 > f1 ? 1 : -1);
x2 = cx + rx * Math.cos(f2);
y2 = cy + ry * Math.sin(f2);
res = a2c(x2, y2, rx, ry, angle, 0, sweep_flag, x2old, y2old, [f2, f2old, cx, cy]);
}
df = f2 - f1;
var c1 = Math.cos(f1),
s1 = Math.sin(f1),
c2 = Math.cos(f2),
s2 = Math.sin(f2),
t = Math.tan(df / 4),
hx = 4 / 3 * rx * t,
hy = 4 / 3 * ry * t,
m = [
- hx * s1, hy * c1,
x2 + hx * s2 - x1, y2 - hy * c2 - y1,
x2 - x1, y2 - y1
];
if (recursive) {
return m.concat(res);
} else {
res = m.concat(res);
var newres = [];
for (var i = 0, n = res.length; i < n; i++) {
newres[i] = i % 2 ? rotateY(res[i - 1], res[i], rad) : rotateX(res[i], res[i + 1], rad);
}
return newres;
}
};

@@ -54,7 +54,27 @@ 'use strict';

var simple = true,
scalex = 1,
scaley = 1,
rotate = 0;
// convert transforms objects to the matrices
transforms = transforms.map(function(transform) {
return transform.name === 'martix' ?
transform :
transformToMatrix(transform);
if (transform.name === 'matrix') {
simple = false;
return transform.data;
} else if (simple) {
if (transform.name == 'scale') {
scalex *= transform.data[0];
scaley *= transform.data[1];
} else if (transform.name == 'rotate') {
if (scalex.toFixed(9) == scaley.toFixed(9)) {
rotate += transform.data[0];
} else {
simple = false;
}
} else if (transform.name != 'translate') {
simple = false;
}
}
return transformToMatrix(transform);
});

@@ -68,4 +88,13 @@

})
};
}
if (simple) {
transforms.splitted = {
scalex: scalex,
scaley: scaley,
rotate: rotate,
isSimple: true
}
}
return transforms;

@@ -72,0 +101,0 @@

@@ -45,6 +45,9 @@ 'use strict';

// move group attibutes to the single content element
if (g.attrs && g.content.length === 1) {
if (g.hasAttr() && g.content.length === 1) {
var inner = g.content[0];
if (inner.elem && !(g.hasAttr('transform') && g.hasAttr('clip-path') && inner.hasAttr('transform'))) {
if (inner.isElem() && !inner.hasAttr('id') &&
!(g.hasAttr('clip-path') &&
(g.hasAttr('transform') || inner.hasAttr('transform')))
) {
g.eachAttr(function(attr) {

@@ -62,3 +65,3 @@ if (!inner.hasAttr(attr.name)) {

// collapse groups without attributes
if (!g.attrs) {
if (!g.hasAttr()) {
unflatten = true;

@@ -65,0 +68,0 @@

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

subpathPoint = [0, 0],
mM = false;
mM = false,
baseItem;

@@ -121,2 +122,3 @@ path.forEach(function(item, index) {

subpathPoint = point.slice(-2);
baseItem = item;
}

@@ -151,2 +153,3 @@

subpathPoint = point.slice(-2);
baseItem = item;

@@ -245,3 +248,3 @@ }

else {
item.coords = subpathPoint.slice(0);
item.coords = baseItem.coords;
point = subpathPoint;

@@ -272,3 +275,3 @@ mM = false;

path = path.filter(function(item) {
path = path.filter(function(item, index) {

@@ -501,2 +504,3 @@ var instruction = item.instruction,

) {
path[index] = prev;
return false;

@@ -511,2 +515,3 @@ }

) {
path[index] = prev;
return false;

@@ -596,2 +601,4 @@ }

prev.data = prev.data.concat(adata);
prev.coords = item.coords;
path[index] = prev;
return false;

@@ -601,2 +608,4 @@ }

prev.data = prev.data.concat(data);
prev.coords = item.coords;
path[index] = prev;
return false;

@@ -632,3 +641,3 @@ }

(
!item.data ||
'Mmz'.indexOf(item.instruction) > -1 ||
'hv'.indexOf(item.instruction) > -1 && (prev.data[0] >= 0) == (item.data[0] >= 0) ||

@@ -641,2 +650,5 @@ !params.utilizeAbsolute

prev.data[0] += item.data[0];
} else if (item.instruction.toLowerCase() === 'm') {
prev.data[0] += item.data[0];
prev.data[1] += item.data[1];
// concat previous data with current if it is not z

@@ -646,2 +658,3 @@ } else if (item.data) {

}
prev.coords = item.coords;

@@ -648,0 +661,0 @@ // filter out current item

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

!item.isEmpty() &&
!item.someAttr(function(attr) { return ~attr.value.indexOf('url(') }) &&
item.content.every(function(inner) {

@@ -40,0 +41,0 @@ return inner.isElem(pathElems);

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

exports.active = true;
exports.active = false;

@@ -8,0 +8,0 @@ exports.params = {

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

* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) ] remove non-inheritable group's "presentation" attributes
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) ] remove useless stroke and fill attrs.
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) ] remove useless stroke and fill attrs (disabled by default)
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) ] remove unused namespaces declaration

@@ -43,0 +43,0 @@ * [ [>](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) ] remove unused and minify used IDs

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

* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeMetadata.js) ] удаление `<metadata>`
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) ] удаление `<title>`
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) ] удаление `<title>` (отключена по умолчанию)
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) ] удаление `<desc>` (отключена по умолчанию)
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeEditorsNSData.js) ] удаление пространств имён различных редакторов, их элементов и атрибутов

@@ -41,2 +42,3 @@ * [ [>](https://github.com/svg/svgo/blob/master/plugins/removeEmptyAttrs.js) ] удаление пустых атрибутов

* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) ] удаление ненаследуемых "презентационных" атрибутов групп
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) ] удаление неиспользуемых атрибутов stroke-* и fill-* (выключено по умолчанию)
* [ [>](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) ] удаление деклараций неиспользуемых пространств имён

@@ -43,0 +45,0 @@ * [ [>](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) ] удаление неиспользуемых и сокращение используемых ID

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc