New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

svgstore

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svgstore - npm Package Compare versions

Comparing version 1.0.0 to 1.1.0

src/utils/svg-to-symbol.js

2

examples/make.js

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

fs.writeFileSync('./sprites.svg', sprites.toString());
fs.writeFileSync('./sprites.svg', sprites);
{
"name": "svgstore",
"version": "1.0.0",
"version": "1.1.0",
"description": "Combines mulitple svg files into one.",

@@ -8,11 +8,7 @@ "main": "src/svgstore.js",

"coveralls": "nyc report -r text-lcov | coveralls",
"pretest": "xo src/*.js test/*.js",
"test": "nyc ava -v",
"test": "xo src/*.js test/*.js; nyc ava -v",
"posttest": "nyc report -r lcov",
"watch": "chokidar '{src,test}/**/*.js' -c 'npm test'"
},
"repository": {
"type": "git",
"url": "https://github.com/shannonmoeller/svgstore.git"
},
"repository": "shannonmoeller/svgstore",
"keywords": [

@@ -38,10 +34,11 @@ "concat",

"dependencies": {
"cheerio": "^0.20.0"
"cheerio": "^0.20.0",
"object-assign": "^4.1.0"
},
"devDependencies": {
"ava": "^0.12.0",
"ava": "0.15.2",
"chokidar-cli": "^1.2.0",
"coveralls": "^2.11.6",
"nyc": "^6.0.0",
"xo": "^0.12.1"
"nyc": "^7.0.0",
"xo": "^0.16"
},

@@ -48,0 +45,0 @@ "engines": {

# `svgstore`
[![NPM version][npm-img]][npm-url] [![Downloads][downloads-img]][npm-url] [![Build Status][travis-img]][travis-url] [![Coverage Status][coveralls-img]][coveralls-url] [![Chat][gitter-img]][gitter-url] [![Tip][amazon-img]][amazon-url]
[![NPM version][npm-img]][npm-url] [![Downloads][downloads-img]][npm-url] [![Build Status][travis-img]][travis-url] [![Coverage Status][coveralls-img]][coveralls-url]

@@ -21,3 +21,3 @@ Combines multiple svg files into one using `<symbol>` elements which you may [`<use>` in your markup](https://css-tricks.com/svg-sprites-use-better-icon-fonts/). Heavily inspired by [`grunt-svgstore`](https://github.com/FWeinb/grunt-svgstore) and [`gulp-svgstore`](https://github.com/w0rm/gulp-svgstore), this is a standalone module that may be used in any asset pipeline.

fs.writeFileSync('./sprites.svg', sprites.toString());
fs.writeFileSync('./sprites.svg', sprites);
```

@@ -38,4 +38,6 @@

### svgstore(): SvgStore
### svgstore([options]): SvgStore
- `options` `{Object}`: [Options for converting SVGs to symbols](#svgstore-options)
Creates a container svg sprites document.

@@ -47,6 +49,7 @@

### .add(id, svg): SvgStore
### .add(id, svg [, options]): SvgStore
- `id` `String` Unique `id` for this svg file.
- `svg` `String` Raw source of the svg file.
- `options` `{Object}` Same as the [options of `svgstore()`](#svgstore-options), but will only apply to this svg file.

@@ -62,2 +65,8 @@ Appends a file to the sprite with the given `id`.

## <a name="svgstore-options"></a>Options
- `cleanDefs` `{Boolean|Array}` (default: `false`) Remove `style` attributes from SVG definitions, or a list of attributes to remove.
- `cleanObjects` `{Boolean|Array}` (default: `false`) Remove `style` attributes from SVG objects, or a list of attributes to remove.
- `customSymbolAttrs` `{Array}` (default: `[]`) Custom attributes to have `svgstore` attempt to copy to the newly created `<symbol/>` tag from the root SVG. These will be searched for in addition to `id`, `viewBox`, `aria-labelledby`, and `role`.
## Contribute

@@ -77,12 +86,8 @@

[amazon-img]: https://img.shields.io/badge/amazon-tip_jar-yellow.svg?style=flat-square
[amazon-url]: https://www.amazon.com/gp/registry/wishlist/1VQM9ID04YPC5?sort=universal-price
[coveralls-img]: http://img.shields.io/coveralls/shannonmoeller/svgstore/master.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/shannonmoeller/svgstore
[coveralls-img]: http://img.shields.io/coveralls/svgstore/svgstore/master.svg?style=flat-square
[coveralls-url]: https://coveralls.io/r/svgstore/svgstore
[downloads-img]: http://img.shields.io/npm/dm/svgstore.svg?style=flat-square
[gitter-img]: http://img.shields.io/badge/gitter-join_chat-1dce73.svg?style=flat-square
[gitter-url]: https://gitter.im/shannonmoeller/shannonmoeller
[npm-img]: http://img.shields.io/npm/v/svgstore.svg?style=flat-square
[npm-url]: https://npmjs.org/package/svgstore
[travis-img]: http://img.shields.io/travis/shannonmoeller/svgstore.svg?style=flat-square
[travis-url]: https://travis-ci.org/shannonmoeller/svgstore
[travis-img]: http://img.shields.io/travis/svgstore/svgstore.svg?style=flat-square
[travis-url]: https://travis-ci.org/svgstore/svgstore
'use strict';
var assign = require('object-assign');
var cheerio = require('cheerio');
var ATTRIBUTE_ID = 'id';
var ATTRIBUTE_VIEW_BOX = 'viewBox';
var svgToSymbol = require('./utils/svg-to-symbol');

@@ -12,3 +12,2 @@ var SELECTOR_DEFS = 'defs';

var TEMPLATE_SVG = '<svg xmlns="http://www.w3.org/2000/svg"><defs/></svg>';
var TEMPLATE_SYMBOL = '<symbol/>';
var TEMPLATE_DOCTYPE = '<?xml version="1.0" encoding="UTF-8"?>' +

@@ -18,2 +17,8 @@ '<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ' +

var DEFAULT_OPTIONS = {
cleanDefs: false,
cleanObjects: false,
customSymbolAttrs: []
};
function load(text) {

@@ -23,3 +28,25 @@ return cheerio.load(text, {xmlMode: true});

function svgstore() {
function clean($, el, attrs) {
var localAttrs = attrs;
if (typeof localAttrs === 'boolean') {
localAttrs = ['style'];
}
if (!localAttrs || !localAttrs.length) {
return el;
}
el.find('*').each(function (i, el) {
localAttrs.forEach(function (attr) {
$(el).removeAttr(attr);
});
});
return el;
}
function svgstore(options) {
var parentOptions = assign({}, DEFAULT_OPTIONS, options);
var parent = load(TEMPLATE_SVG);

@@ -32,19 +59,25 @@ var parentSvg = parent(SELECTOR_SVG);

add: function (id, file) {
add: function (id, file, options) {
var childOptions = assign({}, parentOptions, options);
var child = load(file);
var childSvg = child(SELECTOR_SVG);
var childDefs = child(SELECTOR_DEFS);
var symbol = child(TEMPLATE_SYMBOL);
// merge <defs/>
var cleanDefs = childOptions.cleanDefs;
if (cleanDefs) {
clean(child, childDefs, cleanDefs);
}
parentDefs.append(childDefs.contents());
childDefs.remove();
// clone <svg/> as <symbol/>
symbol.attr(ATTRIBUTE_ID, id);
symbol.attr(ATTRIBUTE_VIEW_BOX, childSvg.attr(ATTRIBUTE_VIEW_BOX));
symbol.append(childSvg.contents());
var childSymbol = svgToSymbol(id, child, childOptions);
// clean <symbol/>
var cleanObjects = childOptions.cleanObjects;
if (cleanObjects) {
clean(child, childSymbol, cleanObjects);
}
// append <symbol/>
parentSvg.append(symbol);
parentSvg.append(childSymbol);

@@ -51,0 +84,0 @@ return this;

@@ -0,35 +1,120 @@

import test from 'ava';
import svgstore from '../src/svgstore';
import test from 'ava';
var doctype = '<?xml version="1.0" encoding="UTF-8"?>' +
const doctype = '<?xml version="1.0" encoding="UTF-8"?>' +
'<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" ' +
'"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">';
test('should create an svg document', async assert => {
var store = svgstore();
var svg = store.toString();
const FIXTURE_SVGS = {
foo: '<svg viewBox="0 0 100 100"><defs><linear-gradient style="fill: red;"/></defs><path style="fill: red;"/></svg>',
bar: '<svg viewBox="0 0 200 200"><defs><radial-gradient style="stroke: red;"/></defs><rect style="stroke: red;"/></svg>',
baz: '<svg viewBox="0 0 200 200"><defs><linear-gradient style="fill: red;"/></defs><path style="fill: red;"/></svg>',
qux: '<svg viewBox="0 0 200 200"><defs><radial-gradient style="stroke: red;" fill="blue"/></defs><rect style="stroke: red;" fill="blue"/></svg>',
quux: '<svg viewBox="0 0 200 200" aria-labelledby="titleId" role="img"><title id="titleId">A boxy shape</title><rect/></svg>',
corge: '<svg viewBox="0 0 200 200" aria-labelledby="titleId" role="img" preserveAspectRatio="xMinYMax" take-me-too="foo" count-me-out="bar">' +
'<title id="titleId">A boxy shape</title><rect/></svg>'
};
assert.is(svg.slice(0, 5), '<?xml');
test('should create an svg document', async t => {
const store = svgstore();
const svg = store.toString();
t.is(svg.slice(0, 5), '<?xml');
});
test('should create an svg element', async assert => {
var store = svgstore();
var svg = store.toString({inline: true});
test('should create an svg element', async t => {
const store = svgstore();
const svg = store.toString({inline: true});
assert.is(svg.slice(0, 4), '<svg');
t.is(svg.slice(0, 4), '<svg');
});
test('should combine svgs', async assert => {
var store = svgstore()
.add('foo', doctype + '<svg viewBox="0 0 100 100"><defs><linear-gradient/></defs><path/></svg>')
.add('bar', doctype + '<svg viewBox="0 0 200 200"><defs><radial-gradient/></defs><rect/></svg>');
test('should combine svgs', async t => {
const store = svgstore()
.add('foo', doctype + FIXTURE_SVGS.foo)
.add('bar', doctype + FIXTURE_SVGS.bar);
var expected = doctype +
const expected = doctype +
'<svg xmlns="http://www.w3.org/2000/svg">' +
'<defs><linear-gradient/><radial-gradient/></defs>' +
'<defs><linear-gradient style="fill: red;"/><radial-gradient style="stroke: red;"/></defs>' +
'<symbol id="foo" viewBox="0 0 100 100"><path style="fill: red;"/></symbol>' +
'<symbol id="bar" viewBox="0 0 200 200"><rect style="stroke: red;"/></symbol>' +
'</svg>';
t.is(store.toString(), expected);
});
test('should clean defs', async t => {
const store = svgstore({cleanDefs: true})
.add('foo', doctype + FIXTURE_SVGS.foo)
.add('bar', doctype + FIXTURE_SVGS.bar)
.add('baz', doctype + FIXTURE_SVGS.baz, {
cleanDefs: []
})
.add('qux', doctype + FIXTURE_SVGS.qux, {
cleanDefs: ['fill']
});
const expected = doctype +
'<svg xmlns="http://www.w3.org/2000/svg">' +
'<defs><linear-gradient/><radial-gradient/><linear-gradient style="fill: red;"/><radial-gradient style="stroke: red;"/></defs>' +
'<symbol id="foo" viewBox="0 0 100 100"><path style="fill: red;"/></symbol>' +
'<symbol id="bar" viewBox="0 0 200 200"><rect style="stroke: red;"/></symbol>' +
'<symbol id="baz" viewBox="0 0 200 200"><path style="fill: red;"/></symbol>' +
'<symbol id="qux" viewBox="0 0 200 200"><rect style="stroke: red;" fill="blue"/></symbol>' +
'</svg>';
t.is(store.toString(), expected);
});
test('should clean objects', async t => {
const store = svgstore({cleanObjects: true})
.add('foo', doctype + FIXTURE_SVGS.foo)
.add('bar', doctype + FIXTURE_SVGS.bar)
.add('baz', doctype + FIXTURE_SVGS.baz, {
cleanObjects: []
})
.add('qux', doctype + FIXTURE_SVGS.qux, {
cleanObjects: ['fill']
});
const expected = doctype +
'<svg xmlns="http://www.w3.org/2000/svg">' +
'<defs><linear-gradient style="fill: red;"/><radial-gradient style="stroke: red;"/><linear-gradient style="fill: red;"/><radial-gradient style="stroke: red;" fill="blue"/></defs>' +
'<symbol id="foo" viewBox="0 0 100 100"><path/></symbol>' +
'<symbol id="bar" viewBox="0 0 200 200"><rect/></symbol>' +
'<symbol id="baz" viewBox="0 0 200 200"><path style="fill: red;"/></symbol>' +
'<symbol id="qux" viewBox="0 0 200 200"><rect style="stroke: red;"/></symbol>' +
'</svg>';
assert.is(store.toString(), expected);
t.is(store.toString(), expected);
});
test('should attempt to preserve the `viewBox`, `aria-labelledby`, and `role` attributes of the root SVG by default', async t => {
const store = svgstore()
.add('quux', FIXTURE_SVGS.quux);
const expected = doctype +
'<svg xmlns="http://www.w3.org/2000/svg">' +
'<defs/>' +
'<symbol id="quux" viewBox="0 0 200 200" aria-labelledby="titleId" role="img"><title id="titleId">A boxy shape</title><rect/></symbol>' +
'</svg>';
t.is(store.toString(), expected);
});
test('should support custom attribute preservation, on top of the defaults', async t => {
const customSymbolAttrs = ['preserveAspectRatio', 'take-me-too'];
const store = svgstore({customSymbolAttrs})
.add('corge', FIXTURE_SVGS.corge);
const expected = doctype +
'<svg xmlns="http://www.w3.org/2000/svg">' +
'<defs/>' +
'<symbol id="corge" viewBox="0 0 200 200" aria-labelledby="titleId" role="img" preserveAspectRatio="xMinYMax" take-me-too="foo">' +
'<title id="titleId">A boxy shape</title><rect/>' +
'</symbol>' +
'</svg>';
t.is(store.toString(), expected);
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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