Socket
Socket
Sign inDemoInstall

svgo

Package Overview
Dependencies
103
Maintainers
3
Versions
102
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 1.1.1 to 1.2.0

plugins/removeAttributesBySelector.js

12

CHANGELOG.md

@@ -0,1 +1,13 @@

### [ [>](https://github.com/svg/svgo/tree/v1.2.0) ] 1.2.0 / 24.02.2019
Some goodness from pull-requests.
* Fixed extra blank lines when processing many files (by @panczarny).
* Added `--recursive` option to process folders recursevely with option `-f` (by @dartess).
* Added `removeAttributesBySelector` plugin to remove elements matching a css selector (by @bmease).
* Added `removeOffCanvasPaths` plugin to remove elements outside of the viewbox (by @JoshyPHP).
* `removeAttrs` plugin: added `preserveCurrentColor` color (by @roblevintennis) and 3rd optional filter for a value (by @Herman-Freund).
* Added `reusePaths` plugin to replace duplicated elements with link (by @jhowcrof).
* Added support of comma-separated plugins list in `--disable` and `--enable` options (by @jmwebservices).
* Added option to preserve IDs based on prefix in `cleanupIDs` plugin (by @bkotzz).
* Replaced `colors` dependency with `chalk` (by @xPaw).
### [ [>](https://github.com/svg/svgo/tree/v1.1.1) ] 1.1.1 / 17.09.2018

@@ -2,0 +14,0 @@ * Fixed crash in `SVGO.optimize()` when ‘info’ is absent.

101

lib/svgo/coa.js
/* jshint quotmark: false */
'use strict';
require('colors');
var FS = require('fs'),
PATH = require('path'),
chalk = require('chalk'),
mkdirp = require('mkdirp'),
promisify = require('util.promisify'),

@@ -17,2 +17,3 @@ readdir = promisify(FS.readdir),

decodeSVGDatauri = require('./tools.js').decodeSVGDatauri,
checkIsDir = require('./tools.js').checkIsDir,
regSVGFile = /\.svg$/,

@@ -125,2 +126,7 @@ noop = () => {},

.opt()
.name('recursive').title('Use with \'-f\'. Optimizes *.svg files in folders recursively.')
.short('r').long('recursive')
.flag()
.end()
.opt()
.name('quiet').title('Only output error messages, not regular status messages')

@@ -203,2 +209,7 @@ .short('q').long('quiet')

// --recursive
if (opts.recursive) {
config.recursive = opts.recursive;
}
// --precision

@@ -302,2 +313,4 @@ if (opts.precision) {

function changePluginsState(names, state, config) {
names.forEach(flattenPluginsCbk);
// extend config

@@ -343,2 +356,21 @@ if (config.plugins) {

/**
* Flatten an array of plugins by invoking this callback on each element
* whose value may be a comma separated list of plugins.
*
* @param {String} name Plugin name
* @param {Number} index Plugin index
* @param {Array} names Plugins being traversed
*/
function flattenPluginsCbk(name, index, names)
{
var split = name.split(',');
if(split.length > 1) {
names[index] = split.shift();
names.push.apply(names, split);
}
}
/**
* Optimize SVG files in a directory.

@@ -366,6 +398,7 @@ * @param {Object} config options

function processDirectory(config, dir, files, output) {
// take only *.svg files
var svgFiles = files.filter(name => regSVGFile.test(name));
return svgFiles.length ?
Promise.all(svgFiles.map(name => optimizeFile(config, PATH.resolve(dir, name), PATH.resolve(output, name)))) :
// take only *.svg files, recursively if necessary
var svgFilesDescriptions = getFilesDescriptions(config, dir, files, output);
return svgFilesDescriptions.length ?
Promise.all(svgFilesDescriptions.map(fileDescription => optimizeFile(config, fileDescription.inputPath, fileDescription.outputPath))) :
Promise.reject(new Error(`No SVG files have been found in '${dir}' directory.`));

@@ -375,2 +408,34 @@ }

/**
* Get svg files descriptions
* @param {Object} config options
* @param {string} dir input directory
* @param {Array} files list of file names in the directory
* @param {string} output output directory
* @return {Array}
*/
function getFilesDescriptions(config, dir, files, output) {
const filesInThisFolder = files
.filter(name => regSVGFile.test(name))
.map(name => ({
inputPath: PATH.resolve(dir, name),
outputPath: PATH.resolve(output, name),
}));
return config.recursive ?
[].concat(
filesInThisFolder,
files
.filter(name => checkIsDir(PATH.resolve(dir, name)))
.map(subFolderName => {
const subFolderPath = PATH.resolve(dir, subFolderName);
const subFolderFiles = FS.readdirSync(subFolderPath);
const subFolderOutput = PATH.resolve(output, subFolderName);
return getFilesDescriptions(config, subFolderPath, subFolderFiles, subFolderOutput);
})
.reduce((a, b) => [].concat(a, b), [])
) :
filesInThisFolder;
}
/**
* Read SVG file and pass to processing.

@@ -433,5 +498,9 @@ * @param {Object} config options

}
mkdirp.sync(PATH.dirname(output));
return writeFile(output, data, 'utf8').catch(error => checkWriteFileError(input, output, data, error));
}
/**

@@ -456,3 +525,3 @@ * Write a time taken by optimization.

(profitPercents < 0 ? ' + ' : ' - ') +
String(Math.abs((Math.round(profitPercents * 10) / 10)) + '%').green + ' = ' +
chalk.green(Math.abs((Math.round(profitPercents * 10) / 10)) + '%') + ' = ' +
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB'

@@ -496,14 +565,2 @@ );

/**
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
* @param {string} path
*/
function checkIsDir(path) {
try {
return FS.lstatSync(path).isDirectory();
} catch(e) {
return false;
}
}
/**
* Show list of available plugins with short description.

@@ -517,3 +574,3 @@ */

.sort((a, b) => a.name.localeCompare(b.name))
.map(plugin => ` [ ${plugin.name.green} ] ${plugin.description}`)
.map(plugin => ` [ ${chalk.green(plugin.name)} ] ${plugin.description}`)
.join('\n');

@@ -529,5 +586,5 @@ console.log(list);

function printErrorAndExit(error) {
console.error(error);
console.error(chalk.red(error));
process.exit(1);
return Promise.reject(error); // for tests
}
}

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

} else {
this.config = defaults;
this.config = Object.assign({}, defaults);
}

@@ -63,0 +63,0 @@

'use strict';
var FS = require('fs');
/**

@@ -151,1 +153,14 @@ * Encode plain SVG data string into Data URI string.

};
/**
* Synchronously check if path is a directory. Tolerant to errors like ENOENT.
* @param {string} path
*/
exports.checkIsDir = function(path) {
try {
return FS.lstatSync(path).isDirectory();
} catch(e) {
return false;
}
};
{
"name": "svgo",
"version": "1.1.1",
"version": "1.2.0",
"description": "Nodejs-based tool for optimizing SVG vector graphics files",

@@ -52,14 +52,14 @@ "keywords": [

"dependencies": {
"coa": "~2.0.1",
"colors": "~1.1.2",
"chalk": "^2.4.1",
"coa": "^2.0.2",
"css-select": "^2.0.0",
"css-select-base-adapter": "~0.1.0",
"css-select-base-adapter": "^0.1.1",
"css-tree": "1.0.0-alpha.28",
"css-url-regex": "^1.1.0",
"csso": "^3.5.0",
"csso": "^3.5.1",
"js-yaml": "^3.12.0",
"mkdirp": "~0.5.1",
"object.values": "^1.0.4",
"object.values": "^1.1.0",
"sax": "~1.2.4",
"stable": "~0.1.6",
"stable": "^0.1.8",
"unquote": "~1.1.1",

@@ -69,3 +69,3 @@ "util.promisify": "~1.0.0"

"devDependencies": {
"coveralls": "~3.0.0",
"coveralls": "^3.0.3",
"fs-extra": "~4.0.3",

@@ -72,0 +72,0 @@ "istanbul": "~0.4.5",

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

'http://ns.adobe.com/XPath/1.0/',
'http://schemas.microsoft.com/visio/2003/SVGExtensions/'
'http://schemas.microsoft.com/visio/2003/SVGExtensions/',
'http://taptrix.com/vectorillustrator/svg_extensions',
'http://www.figma.com/figma/ns',
'http://purl.org/dc/elements/1.1/',
'http://creativecommons.org/ns#',
'http://www.w3.org/1999/02/22-rdf-syntax-ns#',
'http://www.serif.com/',
'http://www.vector.evaxdesign.sk'
];

@@ -2286,0 +2293,0 @@

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

preserve: [],
preservePrefixes: [],
force: false

@@ -45,2 +46,3 @@ };

preserveIDs = new Set(Array.isArray(params.preserve) ? params.preserve : params.preserve ? [params.preserve] : []),
preserveIDPrefixes = new Set(Array.isArray(params.preservePrefixes) ? params.preservePrefixes : (params.preservePrefixes ? [params.preservePrefixes] : [])),
idValuePrefix = '#',

@@ -59,3 +61,3 @@ idValuePostfix = '.';

// quit if <style> of <script> presents ('force' param prevents quitting)
// quit if <style> or <script> present ('force' param prevents quitting)
if (!params.force) {

@@ -130,3 +132,3 @@ if (item.isElem(styleOrScript)) {

// replace referenced IDs with the minified ones
if (params.minify && !preserveIDs.has(key)) {
if (params.minify && !preserveIDs.has(key) && !idMatchesPrefix(preserveIDPrefixes, key)) {
currentIDstring = getIDstring(currentID = generateID(currentID), params);

@@ -148,3 +150,3 @@ IDs.get(key).attr('id').value = currentIDstring;

for(var keyElem of IDs) {
if (!preserveIDs.has(keyElem[0])) {
if (!preserveIDs.has(keyElem[0]) && !idMatchesPrefix(preserveIDPrefixes, keyElem[0])) {
keyElem[1].removeAttr('id');

@@ -158,2 +160,16 @@ }

/**
* Check if an ID starts with any one of a list of strings.
*
* @param {Array} of prefix strings
* @param {String} current ID
* @return {Boolean} if currentID starts with one of the strings in prefixArray
*/
function idMatchesPrefix(prefixArray, currentID) {
if (!currentID) return false;
for (var prefix of prefixArray) if (currentID.startsWith(prefix)) return true;
return false;
}
/**
* Generate unique minimal ID.

@@ -160,0 +176,0 @@ *

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

elemSeparator: DEFAULT_SEPARATOR,
preserveCurrentColor: false,
attrs: []

@@ -23,8 +24,12 @@ };

*
* @param preserveCurrentColor
* format: boolean
*
* @param attrs:
*
* format: [ element* : attribute* ]
* format: [ element* : attribute* : value* ]
*
* element : regexp (wrapped into ^...$), single * or omitted > all elements
* element : regexp (wrapped into ^...$), single * or omitted > all elements (must be present when value is used)
* attribute : regexp (wrapped into ^...$)
* value : regexp (wrapped into ^...$), single * or omitted > all values
*

@@ -42,3 +47,7 @@ * examples:

*
* > remove fill attribute on path element where value is none
* ---
* attrs: 'path:fill:none'
*
*
* > remove all fill and stroke attribute

@@ -62,3 +71,7 @@ * ---

*
* [is same as]
*
* attrs: '.*:(fill|stroke):.*'
*
*
* > remove all stroke related attributes

@@ -76,3 +89,2 @@ * ----

exports.fn = function(item, params) {
// wrap into an array if params is not

@@ -85,2 +97,3 @@ if (!Array.isArray(params.attrs)) {

var elemSeparator = typeof params.elemSeparator == 'string' ? params.elemSeparator : DEFAULT_SEPARATOR;
var preserveCurrentColor = typeof params.preserveCurrentColor == 'boolean' ? params.preserveCurrentColor : false;

@@ -90,8 +103,12 @@ // prepare patterns

// apply to all elements if specifc element is omitted
// if no element separators (:), assume it's attribute name, and apply to all elements *regardless of value*
if (pattern.indexOf(elemSeparator) === -1) {
pattern = ['.*', elemSeparator, pattern].join('');
pattern = ['.*', elemSeparator, pattern, elemSeparator, '.*'].join('');
// if only 1 separator, assume it's element and attribute name, and apply regardless of attribute value
} else if (pattern.split(elemSeparator).length < 3) {
pattern = [pattern, elemSeparator, '.*'].join('');
}
// create regexps for element and attribute name
// create regexps for element, attribute name, and attribute value
return pattern.split(elemSeparator)

@@ -117,6 +134,15 @@ .map(function(value) {

var name = attr.name;
var value = attr.value;
var isFillCurrentColor = preserveCurrentColor && name == 'fill' && value == 'currentColor';
var isStrokeCurrentColor = preserveCurrentColor && name == 'stroke' && value == 'currentColor';
if (!(isFillCurrentColor || isStrokeCurrentColor)) {
// matches attribute name
if (pattern[1].test(name)) {
item.removeAttr(name);
if (pattern[1].test(name)) {
// matches attribute value
if (pattern[2].test(attr.value)) {
item.removeAttr(name);
}
}
}

@@ -123,0 +149,0 @@

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

| [removeUnusedNS](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) | remove unused namespaces declaration |
| [prefixIds](https://github.com/svg/svgo/blob/master/plugins/prefixIds.js) | prefix IDs and classes with the SVG filename or an arbitrary string |
| [cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) | remove unused and minify used IDs |

@@ -62,7 +63,10 @@ | [cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) | round numeric values to the fixed precision, remove default `px` units |

| [removeAttrs](https://github.com/svg/svgo/blob/master/plugins/removeAttrs.js) | remove attributes by pattern (disabled by default) |
| [removeAttributesBySelector](https://github.com/svg/svgo/blob/master/plugins/removeAttributesBySelector.js) | removes attributes of elements that match a css selector (disabled by default) |
| [removeElementsByAttr](https://github.com/svg/svgo/blob/master/plugins/removeElementsByAttr.js) | remove arbitrary elements by ID or className (disabled by default) |
| [addClassesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addClassesToSVGElement.js) | add classnames to an outer `<svg>` element (disabled by default) |
| [addAttributesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addAttributesToSVGElement.js) | adds attributes to an outer `<svg>` element (disabled by default) |
| [removeOffCanvasPaths](https://github.com/svg/svgo/blob/master/plugins/removeOffCanvasPaths.js) | removes elements that are drawn outside of the viewbox (disabled by default) |
| [removeStyleElement](https://github.com/svg/svgo/blob/master/plugins/removeStyleElement.js) | remove `<style>` elements (disabled by default) |
| [removeScriptElement](https://github.com/svg/svgo/blob/master/plugins/removeScriptElement.js) | remove `<script>` elements (disabled by default) |
| [reusePaths](https://github.com/svg/svgo/blob/master/plugins/reusePaths.js) | Find duplicated <path> elements and replace them with <use> links (disabled by default) |

@@ -95,4 +99,4 @@ Want to know how it works and how to write your own plugin? [Of course you want to](https://github.com/svg/svgo/blob/master/docs/how-it-works/en.md). ([동작방법](https://github.com/svg/svgo/blob/master/docs/how-it-works/ko.md))

--config=CONFIG : Config file or JSON string to extend or replace default
--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)
--disable=PLUGIN : Disable plugin by name, "--disable=PLUGIN1,PLUGIN2" for multiple plugins
--enable=PLUGIN : Enable plugin by name, "--enable=PLUGIN3,PLUGIN4" for multiple plugins
--datauri=DATAURI : Output as Data URI string (base64, URI encoded or unencoded)

@@ -102,2 +106,3 @@ --multipass : Enable multipass

--indent=INDENT : Indent number when pretty printing SVGs
-r, --recursive : Use with '-f'. Optimizes *.svg files in folders recursively.
-q, --quiet : Only output error messages, not regular status messages

@@ -104,0 +109,0 @@ --show-plugins : Show available plugins and exit

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

| [removeUnusedNS](https://github.com/svg/svgo/blob/master/plugins/removeUnusedNS.js) | удаление деклараций неиспользуемых пространств имён |
| [prefixIds](https://github.com/svg/svgo/blob/master/plugins/prefixIds.js) | добавляет префикс в ID или классы в виде имени файла или произвольной строки |
| [cleanupIDs](https://github.com/svg/svgo/blob/master/plugins/cleanupIDs.js) | удаление неиспользуемых и сокращение используемых ID |

@@ -56,3 +57,3 @@ | [cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) | округление дробных чисел до заданной точности, удаление `px` как единицы |измерения по-умолчанию

| [collapseGroups](https://github.com/svg/svgo/blob/master/plugins/collapseGroups.js) | схлопывание бесполезных групп `<g>` |
| [removeRasterImage](https://github.com/svg/svgo/blob/master/plugins/removeRasterImages.js) | удаление растровых изображений (выключено по умолчанию) |
| [removeRasterImages](https://github.com/svg/svgo/blob/master/plugins/removeRasterImages.js) | удаление растровых изображений (выключено по умолчанию) |
| [mergePaths](https://github.com/svg/svgo/blob/master/plugins/mergePaths.js) | склеивание нескольких Path в одну кривую |

@@ -63,7 +64,10 @@ | [convertShapeToPath](https://github.com/svg/svgo/blob/master/plugins/convertShapeToPath.js) | конвертирование простых форм в Path |

| [removeAttrs](https://github.com/svg/svgo/blob/master/plugins/removeAttrs.js) | удаляет атрибуты по указанному паттерну (выключено по умолчанию) |
| [removeAttributesBySelector](https://github.com/svg/svgo/blob/master/plugins/removeAttributesBySelector.js) | удаляет атрибуты по CSS-селектору (выключено по умолчанию) |
| [removeElementsByAttr](https://github.com/svg/svgo/blob/master/plugins/removeElementsByAttr.js) | удаляет элементы по указанным ID или классам (выключено по умолчанию) |
| [addClassesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addClassesToSVGElement.js) | добавляет имена классов корневому элементу `<svg>` (выключено по умолчанию) |
| [addAttributesToSVGElement](https://github.com/svg/svgo/blob/master/plugins/addAttributesToSVGElement.js) | добавляет атрибуты корневому элементу `<svg>` (выключено |по умолчанию)
| [removeOffCanvasPaths](https://github.com/svg/svgo/blob/master/plugins/removeOffCanvasPaths.js) | удаляет элементы вне отрисовываемой области (выключено по умолчанию) |
| [removeStyleElement](https://github.com/svg/svgo/blob/master/plugins/removeStyleElement.js) | удаляет элементы `<style>` (выключено по умолчанию) |
| [removeScriptElement](https://github.com/svg/svgo/blob/master/plugins/removeScriptElement.js) | удаляет элементы `<script>` (выключено по умолчанию) |
| [reusePaths](https://github.com/svg/svgo/blob/master/plugins/reusePaths.js) | Заменяет дублирующиеся элементы <path> ссылками <use> (выключено по умолчанию) |

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

--config=CONFIG : Файл конфигурации (или строка JSON) для расширения и замены настроек
--disable=DISABLE : Выключение плагина по имени
--enable=ENABLE : Включение плагина по имени
--disable=PLUGIN : Выключение плагина по имени, "--disable=PLUGIN1,PLUGIN2" для отключения нескольких плагинов
--enable=PLUGIN : Включение плагина по имени, "--enable=PLUGIN3,PLUGIN4" для отключения нескольких плагинов
--datauri=DATAURI : Результат в виде строки Data URI (base64, URI encoded или unencoded)

@@ -103,2 +107,3 @@ --multipass : Оптимизация в несколько проходов

--indent=INDENT : Размер отступа для удобочитаемого форматирования
-r, --recursive : Совместно с '-f'. Рекурсивно обрабатывать *.svg файлы в папках.
-q, --quiet : Подавляет вывод информации, выводятся только сообщения об ошибках

@@ -105,0 +110,0 @@ --show-plugins : Доступные плагины

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