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

svg-baker

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

svg-baker - npm Package Compare versions

Comparing version 1.2.17 to 1.3.0-alpha.76401928

lib/image.js

39

CHANGELOG.md

@@ -0,1 +1,37 @@

# Change Log
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
<a name="1.3.0-alpha.76401928"></a>
# [1.3.0-alpha.76401928](https://github.com/kisenka/svg-baker/packages/svg-baker/compare/svg-baker@1.2.12...svg-baker@1.3.0-alpha.76401928) (2018-04-09)
### Bug Fixes
* **compiler:** move symbols sort from sprite-factory to compiler ([4690c75](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/4690c75))
* **sprite-factory:** sort symbols by id to get more determined sprite content ([9132e23](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/9132e23))
* make symbol.tree getter immutable ([343dc86](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/343dc86))
* preserve `fill` and `stroke` attrs when transform svg to symbol ([51cb3d5](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/51cb3d5))
* sprite move gradients outside symbol ([c6fcab4](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/c6fcab4))
### Chores
* update script ([7640192](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/7640192))
### Features
* **sprite-factory:** allow to configure usages and styles rendering ([bc63366](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/bc63366))
* **svg-to-symbol-transformation:** preserve fill-* and stroke-* attributes ([edda97d](https://github.com/kisenka/svg-baker/packages/svg-baker/commit/edda97d))
### BREAKING CHANGES
* qwe
<a name="1.2.8"></a>

@@ -18,4 +54,1 @@ ## 1.2.8 (2017-06-15)

* **sprite-factory:** dissapearing use tags when sprite is a part of page DOM ([a8c60ee](https://github.com/kisenka/svg-baker/commit/a8c60ee))

153

lib/compiler.js

@@ -0,97 +1,97 @@

/* eslint-disable new-cap */
const Promise = require('bluebird');
const merge = require('merge-options');
const FileRequest = require('./request');
const RuleSet = require('./rules');
const glob = require('glob-all');
const slugify = require('url-slug');
const { readFile } = require('fs-extra');
const Image = require('./image');
const Sprite = require('./sprite');
const SpriteSymbol = require('./symbol');
const symbolFactory = require('./symbol-factory');
const spriteFactory = require('./sprite-factory');
const StackSprite = require('./stack-sprite');
const SpriteSymbol = require('./sprite-symbol');
const { getBasename } = require('./utils');
const defaultConfig = {
rules: [
{ test: /\.svg$/, value: 'sprite.svg' }
],
symbolFactory,
spriteFactory
};
class Compiler {
static sortSymbols(symbols) {
symbols.sort((leftSymbol, rightSymbol) => {
const leftId = leftSymbol.id;
const rightId = rightSymbol.id;
/**
* @typedef {Object} CompilerConfig
* @property {string} mode 'default' | 'stack'
* @property {SpriteConfig|StackSpriteConfig} spriteConfig
* @property {Sprite|StackSprite} spriteClass
* @property {SpriteSymbol} symbolClass
* @property {function(path: string)} generateSymbolId
*/
static get defaultConfig() {
return {
mode: 'default',
spriteConfig: {},
spriteClass: Sprite,
symbolClass: SpriteSymbol,
generateSymbolId: (path, query = '') => slugify(`${getBasename(path)}${query}`)
};
}
if (leftId === rightId) {
return 0;
}
return leftId < rightId ? -1 : 1;
});
/**
* @param {CompilerConfig} [config]
*/
constructor(config = {}) {
this.symbols = [];
return symbols;
const cfg = merge(this.constructor.defaultConfig, config);
switch (cfg.mode) {
default:
case 'default':
cfg.spriteClass = Sprite;
break;
case 'stack':
cfg.spriteClass = StackSprite;
break;
}
/** @type CompilerConfig */
this.config = cfg;
}
constructor(cfg = {}) {
const config = this.config = merge(defaultConfig, cfg);
this.rules = new RuleSet(config.rules);
this.symbols = [];
/**
* @param {string|Array<string>} files Glob pattern or absolute path or array of them
* @return {Promise<SpriteSymbol>}
*/
glob(files) {
const p = typeof pattern === 'string' ? [files] : files;
return new Promise((resolve, reject) => {
glob(p, { nodir: true, absolute: true }, (err, f) => {
return err ? reject(err) : resolve(f);
});
}).then(paths => this.addFiles(paths));
}
/**
* @param {string} content
* @param {string} path
* @param {string} [id]
* @param {Array<string>} paths
* @return {Promise<SpriteSymbol>}
*/
addSymbol({ path, content, id }) {
const symbols = this.symbols;
const factory = this.config.symbolFactory;
const request = new FileRequest(path);
const options = { id, request, content, factory };
addFiles(paths) {
const { symbolClass, generateSymbolId: generateId } = this.config;
const p = paths.map(path => ({
path,
absolute: path.split('?')[0]
}));
const existing = symbols.find(s => s.request.equals(request));
const existingIndex = existing ? symbols.indexOf(existing) : -1;
const allExceptCurrent = symbols
.filter(s => s.request.fileEquals(request) && !s.request.queryEquals(request))
.map(symbol => ({ symbol, index: symbols.indexOf(symbol) }));
return SpriteSymbol.create(options).then((newSymbol) => {
if (!existing) {
symbols.push(newSymbol);
Compiler.sortSymbols(symbols);
return newSymbol;
}
symbols[existingIndex] = newSymbol;
Compiler.sortSymbols(symbols);
return Promise.map(allExceptCurrent, ({ symbol, index }) => {
const opts = { id: symbol.id, request: symbol.request, content, factory };
return SpriteSymbol.create(opts).then(created => symbols[index] = created);
}).then(() => newSymbol);
});
// eslint-disable-next-line arrow-body-style
return Promise.map(p, ({ path, absolute }) => {
return readFile(absolute).then(content => new Image(path, content));
})
.then(images => images.map(img => new symbolClass(generateId(img.path, img.query), img)))
.then(symbols => {
this.symbols = this.symbols.concat(symbols);
return symbols;
});
}
/**
* @return {Promise<Array<Sprite>>}
* @returns {Promise<Sprite>}
*/
compile() {
const symbols = this.symbols;
const rules = this.rules.rules;
const factory = this.config.spriteFactory;
return Promise.map(rules, (rule) => {
const spriteSymbols = [];
const filename = rule.uri;
symbols.forEach((symbol) => {
const isMatch = rule.match(symbol.request.file);
if (isMatch) {
spriteSymbols.push(symbol);
}
});
return spriteSymbols.length > 0 ?
Sprite.create({ symbols: spriteSymbols, filename, factory }) :
null;
}).filter(result => result !== null);
const { spriteClass, spriteConfig } = this.config;
const sprite = new spriteClass(spriteConfig, this.symbols);
return Promise.resolve(sprite);
}

@@ -101,2 +101,1 @@ }

module.exports = Compiler;
module.exports.defaultConfig = defaultConfig;

@@ -1,27 +0,115 @@

const { renderer } = require('posthtml-svg-mode');
const defaultFactory = require('./sprite-factory');
const merge = require('merge-options');
const SpriteSymbol = require('./sprite-symbol');
const SpriteSymbolsMap = require('./sprite-symbols-map');
const {
generateSpriteTree,
calculateSymbolPosition,
createImageFromFile
} = require('./utils');
class Sprite {
constructor({ tree, filename }) {
this.tree = tree;
this.filename = filename;
/**
* @typedef {Object} SpriteConfig
* @property {string} filename
* @property {Object} attrs
* @property {boolean} usages
* @property {number} spacing
* @return {SpriteConfig}
*/
static get defaultConfig() {
return {
filename: 'sprite.svg',
attrs: {},
usages: true,
spacing: 10
};
}
/**
* @param {Object} options
* @param {Array<SpriteSymbol>} options.symbols
* @param {string} options.filename Output sprite filename
* @param {Function<Promise<PostHTMLProcessingResult>>} [options.factory]
* @return {Promise<Sprite>}
* @param {SpriteConfig} [config]
* @param {Array<SpriteSymbol>} [symbols]
*/
static create(options) {
const { symbols, filename, factory = defaultFactory } = options;
return factory({ symbols }).then(({ tree }) => new Sprite({ tree, filename }));
constructor(config, symbols) {
this.config = merge(this.constructor.defaultConfig, config);
this._symbols = new SpriteSymbolsMap(symbols);
}
/**
* @return {string}
* @return {number}
*/
get width() {
const { symbols } = this;
return symbols.length ? Math.max(...symbols.map(s => s.width)) : 0;
}
/**
* @return {number}
*/
get height() {
const { symbols, config } = this;
const symbolsHeight = symbols
.map(({ image }) => image.height)
.reduce((sum, height) => sum + height, 0);
return symbolsHeight + (symbols.length * config.spacing);
}
/**
* @return {Array<SpriteSymbol>}
*/
get symbols() {
return this._symbols.toArray();
}
/**
* @param {SpriteSymbol} symbol
* @return {SpriteSymbol}
*/
addSymbol(symbol) {
this._symbols.add(symbol);
}
/**
* @param {SpriteSymbol} symbol
* @param {boolean|string} [format] false | 'px' | 'percent'
* @return {SpriteSymbolPosition}
*/
calculateSymbolPosition(symbol, format) {
return calculateSymbolPosition(symbol, this, format);
}
/**
* @return {Promise<PostSvgTree>}
*/
generate() {
const { width, height, config, symbols } = this;
let usagesTrees;
if (config.usages) {
usagesTrees = symbols.map(s => ({
tag: 'use',
attrs: {
width: s.width,
height: s.height,
'xlink:href': `#${s.id}`,
transform: `translate(0, ${calculateSymbolPosition(s, this).top})`
}
}));
}
return Promise.all(symbols.map(s => s.generate()))
.then(symbolsTrees => generateSpriteTree({
attrs: merge(config.attrs, { width, height }),
defs: symbolsTrees,
content: usagesTrees
}));
}
/**
* @return {Promise<string>}
*/
render() {
return renderer(this.tree);
return this.generate().then(tree => tree.toString());
}

@@ -28,0 +116,0 @@ }

@@ -1,17 +0,4 @@

const merge = require('merge-options');
const { getRoot } = require('../utils');
const defaultConfig = {
removeDimensions: false
};
/**
* @param {Object} [config] {@see defaultConfig}
* @return {Function} PostHTML plugin
*/
function normalizeViewBox(config = {}) {
const cfg = merge(defaultConfig, config);
return (tree) => {
const root = getRoot(tree);
module.exports = function normalizeViewBox() {
return tree => {
const root = tree.root;
root.attrs = root.attrs || {};

@@ -22,8 +9,3 @@ const attrs = root.attrs;

if (!viewBox && width && height) {
attrs.viewBox = `0 0 ${parseFloat(width).toString()} ${parseFloat(height).toString()}`;
if (cfg.removeDimensions) {
delete attrs.width;
delete attrs.height;
}
attrs.viewBox = `0 0 ${width} ${height}`;
}

@@ -33,4 +15,2 @@

};
}
module.exports = normalizeViewBox;
};

@@ -6,10 +6,7 @@ const Promise = require('bluebird');

/**
* @return {Function} PostHTML plugin
*/
function prefixStyleSelectors(prefix) {
return (tree) => {
module.exports = function prefixStyleSelectors(prefix) {
return tree => {
const styleNodes = [];
tree.match({ tag: 'style' }, (node) => {
tree.match({ tag: 'style' }, node => {
styleNodes.push(node);

@@ -19,3 +16,3 @@ return node;

return Promise.map(styleNodes, (node) => {
return Promise.map(styleNodes, node => {
const content = node.content ? decodeEntities(node.content.join('')) : '';

@@ -29,5 +26,2 @@

};
}
module.exports = prefixStyleSelectors;
};
const micromatch = require('micromatch');
const merge = require('merge-options');
const { getRoot } = require('../utils');
const defaultConfig = {
id: undefined,
preserve: [
'id',
'viewBox',

@@ -13,3 +12,4 @@ 'preserveAspectRatio',

'stroke?(-*)',
'fill?(-*)'
'fill?(-*)',
'xmlns?(:*)'
]

@@ -22,7 +22,7 @@ };

*/
function svgToSymbol(config = null) {
const cfg = Object.assign({}, defaultConfig, config);
module.exports = function svgToSymbol(config) {
const cfg = merge(defaultConfig, config);
return (tree) => {
const root = getRoot(tree);
return tree => {
const root = tree.root;
root.tag = 'symbol';

@@ -34,3 +34,3 @@ root.attrs = root.attrs || {};

attrNames.forEach((name) => {
attrNames.forEach(name => {
if (!attrNamesToPreserve.includes(name)) {

@@ -50,4 +50,2 @@ delete root.attrs[name];

};
}
module.exports = svgToSymbol;
};
{
"name": "svg-baker",
"version": "1.2.17",
"version": "1.3.0-alpha.76401928",
"description": "",

@@ -8,28 +8,26 @@ "author": "kisenka <qtuzov@gmail.com> (https://github.com/kisenka)",

"license": "MIT",
"repository": "https://github.com/kisenka/svg-baker",
"main": "lib/compiler.js",
"repository": "https://github.com/kisenka/svg-baker/packages/svg-baker",
"files": [
"lib/",
"namespaces.js",
"README.md"
"namespaces.js"
],
"dependencies": {
"bluebird": "^3.5.0",
"clone": "^2.1.1",
"fs-extra": "^5.0.0",
"glob-all": "^3.1.0",
"he": "^1.1.1",
"image-size": "^0.5.1",
"loader-utils": "^1.1.0",
"merge-options": "0.0.64",
"micromatch": "3.1.0",
"postcss": "^5.2.17",
"postcss": "^6.0.21",
"postcss-prefix-selector": "^1.6.0",
"posthtml-rename-id": "^1.0",
"posthtml-svg-mode": "^1.0",
"query-string": "^4.3.2",
"traverse": "^0.6.6"
"postsvg": "^2.0.0",
"query-string": "^6.0.0",
"traverse": "^0.6.6",
"url-slug": "^2.0.0"
},
"scripts": {
"lint": "eslint lib test",
"test": "nyc --reporter=lcov mocha -r ../../test/mocha-setup.js"
"test": "mocha -r $MOCHA_SETUP_PATH "
}
}
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