Comparing version 1.2.17 to 1.3.0-alpha.76401928
@@ -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)) | ||
@@ -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 " | ||
} | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
22559
21
693
14
1
2
1
+ Addedfs-extra@^5.0.0
+ Addedglob-all@^3.1.0
+ Addedpostsvg@^2.0.0
+ Addedurl-slug@^2.0.0
+ Addedansi-regex@5.0.1(transitive)
+ Addedansi-styles@3.2.14.3.0(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedcamelcase@5.3.1(transitive)
+ Addedchalk@2.4.2(transitive)
+ Addedcliui@6.0.0(transitive)
+ Addedclone@1.0.4(transitive)
+ Addedcolor-convert@1.9.32.0.1(transitive)
+ Addedcolor-name@1.1.31.1.4(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addeddecamelize@1.2.0(transitive)
+ Addeddeepmerge@2.2.1(transitive)
+ Addedemoji-regex@8.0.0(transitive)
+ Addedfilter-obj@1.1.0(transitive)
+ Addedfind-up@4.1.0(transitive)
+ Addedfs-extra@5.0.0(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedget-caller-file@2.0.5(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglob-all@3.3.1(transitive)
+ Addedgraceful-fs@4.2.11(transitive)
+ Addedhas-flag@3.0.0(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedis-fullwidth-code-point@3.0.0(transitive)
+ Addedjsonfile@4.0.0(transitive)
+ Addedlocate-path@5.0.0(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedp-limit@2.3.0(transitive)
+ Addedp-locate@4.1.0(transitive)
+ Addedp-try@2.2.0(transitive)
+ Addedpath-exists@4.0.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpostcss@6.0.23(transitive)
+ Addedposthtml@0.11.6(transitive)
+ Addedposthtml-match-helper@1.0.4(transitive)
+ Addedposthtml-parser@0.4.2(transitive)
+ Addedpostsvg@2.2.7(transitive)
+ Addedquery-string@6.14.1(transitive)
+ Addedrequire-directory@2.1.1(transitive)
+ Addedrequire-main-filename@2.0.0(transitive)
+ Addedset-blocking@2.0.0(transitive)
+ Addedsource-map@0.6.1(transitive)
+ Addedsplit-on-first@1.1.0(transitive)
+ Addedstrict-uri-encode@2.0.0(transitive)
+ Addedstring-width@4.2.3(transitive)
+ Addedstrip-ansi@6.0.1(transitive)
+ Addedsupports-color@5.5.0(transitive)
+ Addedunidecode@0.1.8(transitive)
+ Addeduniversalify@0.1.2(transitive)
+ Addedurl-slug@2.3.2(transitive)
+ Addedwhich-module@2.0.1(transitive)
+ Addedwrap-ansi@6.2.0(transitive)
+ Addedwrappy@1.0.2(transitive)
+ Addedy18n@4.0.3(transitive)
+ Addedyargs@15.4.1(transitive)
+ Addedyargs-parser@18.1.3(transitive)
- Removedclone@^2.1.1
- Removedloader-utils@^1.1.0
- Removedposthtml-svg-mode@^1.0
- Removedansi-regex@2.1.1(transitive)
- Removedansi-styles@2.2.1(transitive)
- Removedbig.js@5.2.2(transitive)
- Removedchalk@1.1.3(transitive)
- Removedclone@2.1.2(transitive)
- Removedemojis-list@3.0.0(transitive)
- Removedhas-ansi@2.0.0(transitive)
- Removedhas-flag@1.0.0(transitive)
- Removedjs-base64@2.6.4(transitive)
- Removedjson5@1.0.2(transitive)
- Removedloader-utils@1.4.2(transitive)
- Removedmerge-options@1.0.1(transitive)
- Removedminimist@1.2.8(transitive)
- Removedobject-assign@4.1.1(transitive)
- Removedpostcss@5.2.18(transitive)
- Removedposthtml@0.9.2(transitive)
- Removedposthtml-parser@0.2.1(transitive)
- Removedposthtml-svg-mode@1.0.3(transitive)
- Removedquery-string@4.3.4(transitive)
- Removedstrict-uri-encode@1.1.0(transitive)
- Removedstrip-ansi@3.0.1(transitive)
- Removedsupports-color@2.0.03.2.3(transitive)
Updatedpostcss@^6.0.21
Updatedquery-string@^6.0.0