nav tabs on admin dashboard
This commit is contained in:
11
node_modules/svgo/.npmignore
generated
vendored
11
node_modules/svgo/.npmignore
generated
vendored
@@ -1,11 +0,0 @@
|
||||
docs
|
||||
examples
|
||||
test
|
||||
lib-cov
|
||||
.editorconfig
|
||||
.jshintignore
|
||||
.jshintrc
|
||||
.travis.yml
|
||||
lcov.info
|
||||
logo.svg
|
||||
CHANGELOG.MD
|
||||
7
node_modules/svgo/.svgo.yml
generated
vendored
7
node_modules/svgo/.svgo.yml
generated
vendored
@@ -23,9 +23,11 @@ plugins:
|
||||
- removeXMLNS
|
||||
- removeEditorsNSData
|
||||
- cleanupAttrs
|
||||
- inlineStyles
|
||||
- minifyStyles
|
||||
- convertStyleToAttrs
|
||||
- cleanupIDs
|
||||
- prefixIds
|
||||
- removeRasterImages
|
||||
- removeUselessDefs
|
||||
- cleanupNumericValues
|
||||
@@ -48,16 +50,19 @@ plugins:
|
||||
- removeEmptyContainers
|
||||
- mergePaths
|
||||
- removeUnusedNS
|
||||
- transformsWithOnePath
|
||||
- sortAttrs
|
||||
- removeTitle
|
||||
- removeDesc
|
||||
- removeDimensions
|
||||
- removeAttrs
|
||||
- removeAttributesBySelector
|
||||
- removeElementsByAttr
|
||||
- addClassesToSVGElement
|
||||
- removeStyleElement
|
||||
- removeScriptElement
|
||||
- addAttributesToSVGElement
|
||||
- removeOffCanvasPaths
|
||||
- reusePaths
|
||||
|
||||
# configure the indent (default 4 spaces) used by `--pretty` here:
|
||||
#
|
||||
|
||||
95
node_modules/svgo/CHANGELOG.md
generated
vendored
95
node_modules/svgo/CHANGELOG.md
generated
vendored
@@ -1,8 +1,91 @@
|
||||
### [ [>](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
|
||||
* Fixed crash in `SVGO.optimize()` when ‘info’ is absent.
|
||||
* Removed extra space after `cleanupListOfValues` plugin.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.1.0) ] 1.1.0 / 16.09.2018
|
||||
* Fixed `collapseGroups` plugin removing property with a child having `inherit` value.
|
||||
* `version` attribute value is not more being rounded.
|
||||
* Fixed jsAPI `clone` method with respect to the introduced CSS classes.
|
||||
* Fixed scaling strokes with `vector-effect="non-scaling-stroke"` (by @alexjlockwood).
|
||||
* Fixed passing properties from groups in `collapseGroups` plugin if child have a filter (by @stristr).
|
||||
* Fixed arc path commands parsing without separators after flags, effectively producing a JS error.
|
||||
* Fixed `viewBox` separators parsing.
|
||||
* Fixed `removeNonInheritableGroupAttrs` plugin to work as intended.
|
||||
* Fixed removing path segments without length in presence of `stroke-linecap`.
|
||||
* Fixed `removeUnknownsAndDefaults` plugin removing attributes from elements with `id`.
|
||||
* Fixed converting to large arcs from nearly straight lines curves.
|
||||
* Fixed `collapseGroups` plugin affecting `<switch>` and its subgroups.
|
||||
* Fixed `convertTransform` plugin converting to `rotate()` with wrong sign in some case.
|
||||
* Fixed `cleanupListOfValues` plugin not preserving non-numeric values.
|
||||
* Fixed `!important` being passed to attributes in `convertStyleToAttrs` plugin.
|
||||
* Added option `keepImportant` to `convertStyleToAttrs` plugin to preserve styles with `!important`.
|
||||
* `removeHiddenElems` plugin now also removes elements with `visibility="hidden"` attribute (by @mikolaj92).
|
||||
* Added `forceAbsolutePath` option to `convertPathData` plugin to always use absolute coordinates (by @cool).
|
||||
* Added `keepRoleAttr` for `removeUnknownsAndDefaults` plugin to preserve `role-` attributes (by @himedlooff).
|
||||
* Added `xmlns` order option in `sortAttrs` plugin (by @hellatan).
|
||||
* Added an option to `prefixIds` plugin to pass prefix as false or as a function that returns false (by @vzaidman).
|
||||
* `prefixIds` plugin now adds prefix to every class (by @vzaidman).
|
||||
* Updated and improved docs a bit (multiple authors).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.5) ] 1.0.5 / 26.02.2018
|
||||
* Fixed issue with prefixIDs plugin not replacing url() values correctly (by @harrisjose).
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.4) ] 1.0.4 / 30.01.2018
|
||||
* Fixed bug with removing groups that are direct child of "<switch>".
|
||||
* Fixed bug with shorthand path points counting (thanks @alexjlockwood for noticing).
|
||||
* Fixed crash on parsing invalid transform, e.g. without close parenthesis.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.3) ] 1.0.3 / 08.11.2017
|
||||
* Fixed `removeViewBox` plugin to check for zero start coordinates.
|
||||
* Removed extra info from STDOUT when it set to output.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.2) ] 1.0.2 / 03.11.2017
|
||||
* Fixed a couple of errors related to `inlineStyles` plugin.
|
||||
* Updated some lost details in documentation to reflect v1.0 changes.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.1) ] 1.0.1 / 31.10.2017
|
||||
* Fixed error “Object.defineProperty called on non-object” in images with `<foreignObject/>`.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v1.0.0) ] 1.0.0 / 30.10.2017
|
||||
* SVGO now requires Node 4 or higher.
|
||||
* Changed CLI syntax to treat filenames as input, thus allowing `svgo *.svg` syntax.
|
||||
* `SVGO.optimize()` now returns `Promise`.
|
||||
* Added `datauri` option to JS API.
|
||||
* Added support for SVG 2 `href` attribute.
|
||||
* `cleanupIDs` now don't removes IDs if an image consists only of `defs`.
|
||||
* New plugin `inlineStyles` for converting styles from `<style>` element to attributes if possible (by @strarsis).
|
||||
* `cleanupNumericValues` now rounds values in `viewBox` (by @caub).
|
||||
* New plugin: `removeScriptElement` (disabled by default) to align with `removeStyleElement` (by @pklingem).
|
||||
* `minifyStyles` now removes styles based on usage with controlling options (by @lahmatiy).
|
||||
* New option `except` in `cleanupIDs` to keep IDs (by @Velenir).
|
||||
* New option `force` in `cleanupIDs` to work even if SVG contains `style` or `script` elements (by @Velenir).
|
||||
* Fixed arcs transforming with different signed `scale` parameters (by @JoshyPHP).
|
||||
* Fixed `removeUselessStrokeAndFill` to check for `style` or `script` elements per file (by @caub).
|
||||
* New option `keepAriaAttrs` in `removeUnknownsAndDefaults` (by @davidtheclark).
|
||||
* Corrected parsing in `cleanupIDs` to account animation syntax (by @caub).
|
||||
* `#ff0000` now converts to `red` as well as `#f00` (by @davidleston).
|
||||
* Added “gray” variation to colors list per CSS Color Module Level 4 (by @ydaniv).
|
||||
* Fixed error on empty files.
|
||||
* A separator character in `removeAttrs` now can be changed per `elemSeparator` option (by @mikestreety).
|
||||
* `addAttributesToSVGElement` now can add values to attributes.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.7.2) ] 0.7.2 / 29.01.2017
|
||||
* Extended `currentColor` match conditions (string, rx, bool) (by @AlimovSV)
|
||||
* Fixed removing `<animate>` in `<stop>`.
|
||||
* Fixed removing same transform in inner element in `removeUnknownsAndDefaults`.
|
||||
* Fixed collapsing groups with same non-inheritable attribue.
|
||||
* Fixed collapsing groups with same non-inheritable attribute.
|
||||
* Corrected removing of leading zero in case of exponential notation.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.7.1) ] 0.7.1 / 27.09.2016
|
||||
@@ -26,7 +109,7 @@
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.5) ] 0.6.5 / 25.04.2016
|
||||
* Extra content inserted by editors are now being removed within `<foreignObject>` as well thus fixing bug “Namespace prefix … is not defined“ after applying SVGO.
|
||||
* Doctype with entities declartion is now also being removed since svgo correctly parses them starting from the version [0.6.2](https://github.com/svg/svgo/tree/v0.6.2).
|
||||
* Doctype with entities declaration is now also being removed since svgo correctly parses them starting from the version [0.6.2](https://github.com/svg/svgo/tree/v0.6.2).
|
||||
* Corrected `moveGroupAttrsToElems` not to move attributes to `g` content if it's referenced (has an `id`).
|
||||
* `collapseGroups` now don't collapse a group if it has an animated attribute (SMIL).
|
||||
|
||||
@@ -48,10 +131,10 @@
|
||||
* Fixed error on converting curves to arcs.
|
||||
* Corrected rounding in subsequent passes with `--multipass` option.
|
||||
* Data URI option now handles charset (by @holymonson)
|
||||
* Tranformations are no longer moved to group if there is a mask (`plugins/moveElemsAttrsToGroup.js`).
|
||||
* Transformations are no longer moved to group if there is a mask (`plugins/moveElemsAttrsToGroup.js`).
|
||||
* Fixed matrix decomposition losing sign in case like `[1, 0, 0, -1, 0, 0]` (`scale(1 -1)`).
|
||||
* Fixed crash on uppercased color name.
|
||||
* Paths with `id` and without `stroke-width` aren't being trasformed now since `stroke-width` may be applied later.
|
||||
* Paths with `id` and without `stroke-width` aren't being transformed now since `stroke-width` may be applied later.
|
||||
|
||||
### [ [>](https://github.com/svg/svgo/tree/v0.6.1) ] 0.6.1 / 21.11.2015
|
||||
* Added option `--quiet` to suppress output (by @phihag).
|
||||
@@ -63,9 +146,9 @@
|
||||
* New optimization: circular curves now being converted to arcs. A notable improvement for circles within paths.
|
||||
* New plugin “[minifyStyles](https://github.com/svg/svgo/blob/master/plugins/minifyStyles.js)” which minifies `<style>` elments content with CSSO by @strarsis (svgo still doesn't understand its content)
|
||||
* New plugin “[removeStyleElement](https://github.com/svg/svgo/blob/master/plugins/removeStyleElement.js)” (disabled by default) by @betsydupuis.
|
||||
* Fixed issues wuth parsing numbers with exponent fraction (could happen with high precision >= 7).
|
||||
* Fixed issues with parsing numbers with exponent fraction (could happen with high precision >= 7).
|
||||
* Fixed rounding error due to incorrect preserving of precision in transformations.
|
||||
* Fixed shortand curve distortion due to converted previous curve to not a curve.
|
||||
* Fixed shorthand curve distortion due to converted previous curve to not a curve.
|
||||
* Fixed interoperability issue with `precision` cli-option and `full` config.
|
||||
* Fixed an error produced by “[removeUnknownsAndDefaults](https://github.com/svg/svgo/blob/master/plugins/removeUnknownsAndDefaults.js)” by @thiakil
|
||||
* Another Inkscape prefix namespace is being removed.
|
||||
|
||||
6
node_modules/svgo/Makefile
generated
vendored
6
node_modules/svgo/Makefile
generated
vendored
@@ -13,9 +13,9 @@ coveralls: lib-cov
|
||||
@cat lcov.info | ./node_modules/.bin/coveralls
|
||||
@rm -rf lib-cov lcov.info
|
||||
|
||||
travis: jshint test coveralls
|
||||
travis: lint test coveralls
|
||||
|
||||
jshint:
|
||||
@npm run jshint
|
||||
lint:
|
||||
@npm run lint
|
||||
|
||||
.PHONY: test
|
||||
|
||||
100
node_modules/svgo/README.md
generated
vendored
100
node_modules/svgo/README.md
generated
vendored
@@ -3,14 +3,14 @@
|
||||
|
||||
<img src="https://svg.github.io/svgo-logo.svg" width="200" height="200" alt="logo"/>
|
||||
|
||||
## SVGO [](https://npmjs.org/package/svgo) [](https://gemnasium.com/svg/svgo) [](https://travis-ci.org/svg/svgo) [](https://coveralls.io/r/svg/svgo?branch=master)
|
||||
## SVGO [](https://npmjs.org/package/svgo) [](https://travis-ci.org/svg/svgo) [](https://coveralls.io/r/svg/svgo?branch=master)
|
||||
|
||||
**SVG O**ptimizer is a Nodejs-based tool for optimizing SVG vector graphics files.
|
||||

|
||||
|
||||
## Why?
|
||||
|
||||
SVG files, especially exported from various editors, usually contain a lot of redundant and useless information such as editor metadata, comments, hidden elements, default or non-optimal values and other stuff that can be safely removed or converted without affecting SVG rendering result.
|
||||
SVG files, especially those exported from various editors, usually contain a lot of redundant and useless information. This can include editor metadata, comments, hidden elements, default or non-optimal values and other stuff that can be safely removed or converted without affecting the SVG rendering result.
|
||||
|
||||
## What it can do
|
||||
|
||||
@@ -19,14 +19,15 @@ SVGO has a plugin-based architecture, so almost every optimization is a separate
|
||||
Today we have:
|
||||
|
||||
| Plugin | Description |
|
||||
| ------ | ----------- |
|
||||
| ------ | ----------- |
|
||||
| [cleanupAttrs](https://github.com/svg/svgo/blob/master/plugins/cleanupAttrs.js) | cleanup attributes from newlines, trailing, and repeating spaces |
|
||||
| [inlineStyles](https://github.com/svg/svgo/blob/master/plugins/inlineStyles.js) | move and merge styles from `<style>` elements to element `style` attributes |
|
||||
| [removeDoctype](https://github.com/svg/svgo/blob/master/plugins/removeDoctype.js) | remove doctype declaration |
|
||||
| [removeXMLProcInst](https://github.com/svg/svgo/blob/master/plugins/removeXMLProcInst.js) | remove XML processing instructions |
|
||||
| [removeComments](https://github.com/svg/svgo/blob/master/plugins/removeComments.js) | remove comments |
|
||||
| [removeMetadata](https://github.com/svg/svgo/blob/master/plugins/removeMetadata.js) | remove `<metadata>` |
|
||||
| [removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) | remove `<title>` (disabled by default) |
|
||||
| [removeDesc](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) | remove `<desc>` (only non-meaningful by default) |
|
||||
| [removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) | remove `<title>` |
|
||||
| [removeDesc](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) | remove `<desc>` |
|
||||
| [removeUselessDefs](https://github.com/svg/svgo/blob/master/plugins/removeUselessDefs.js) | remove elements of `<defs>` without `id` |
|
||||
| [removeXMLNS](https://github.com/svg/svgo/blob/master/plugins/removeXMLNS.js) | removes `xmlns` attribute (for inline svg, disabled by default) |
|
||||
| [removeEditorsNSData](https://github.com/svg/svgo/blob/master/plugins/removeEditorsNSData.js) | remove editors namespaces, elements, and attributes |
|
||||
@@ -34,7 +35,7 @@ Today we have:
|
||||
| [removeHiddenElems](https://github.com/svg/svgo/blob/master/plugins/removeHiddenElems.js) | remove hidden elements |
|
||||
| [removeEmptyText](https://github.com/svg/svgo/blob/master/plugins/removeEmptyText.js) | remove empty Text elements |
|
||||
| [removeEmptyContainers](https://github.com/svg/svgo/blob/master/plugins/removeEmptyContainers.js) | remove empty Container elements |
|
||||
| [removeViewBox](https://github.com/svg/svgo/blob/master/plugins/removeViewBox.js) | remove `viewBox` attribute when possible (disabled by default) |
|
||||
| [removeViewBox](https://github.com/svg/svgo/blob/master/plugins/removeViewBox.js) | remove `viewBox` attribute when possible |
|
||||
| [cleanupEnableBackground](https://github.com/svg/svgo/blob/master/plugins/cleanupEnableBackground.js) | remove or cleanup `enable-background` attribute when possible |
|
||||
| [minifyStyles](https://github.com/svg/svgo/blob/master/plugins/minifyStyles.js) | minify `<style>` elements content with [CSSO](https://github.com/css/csso) |
|
||||
| [convertStyleToAttrs](https://github.com/svg/svgo/blob/master/plugins/convertStyleToAttrs.js) | convert styles into attributes |
|
||||
@@ -45,9 +46,10 @@ Today we have:
|
||||
| [removeNonInheritableGroupAttrs](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) | remove non-inheritable group's "presentation" attributes |
|
||||
| [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) | remove useless `stroke` and `fill` attrs |
|
||||
| [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 |
|
||||
| [cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) | round numeric values to the fixed precision, remove default `px` units |
|
||||
| [cleanupListOfValues](https://github.com/svg/svgo/blob/master/plugins/cleanupListOfValues.js) | round numeric values in attributes that take a list of numbers (like `viewBox` or `enableBackground`) |
|
||||
| [cleanupListOfValues](https://github.com/svg/svgo/blob/master/plugins/cleanupListOfValues.js) | round numeric values in attributes that take a list of numbers (like `viewBox` or `enable-background`) |
|
||||
| [moveElemsAttrsToGroup](https://github.com/svg/svgo/blob/master/plugins/moveElemsAttrsToGroup.js) | move elements' attributes to their enclosing group |
|
||||
| [moveGroupAttrsToElems](https://github.com/svg/svgo/blob/master/plugins/moveGroupAttrsToElems.js) | move some group attributes to the contained elements |
|
||||
| [collapseGroups](https://github.com/svg/svgo/blob/master/plugins/collapseGroups.js) | collapse useless groups |
|
||||
@@ -55,23 +57,30 @@ Today we have:
|
||||
| [mergePaths](https://github.com/svg/svgo/blob/master/plugins/mergePaths.js) | merge multiple Paths into one |
|
||||
| [convertShapeToPath](https://github.com/svg/svgo/blob/master/plugins/convertShapeToPath.js) | convert some basic shapes to `<path>` |
|
||||
| [sortAttrs](https://github.com/svg/svgo/blob/master/plugins/sortAttrs.js) | sort element attributes for epic readability (disabled by default) |
|
||||
| [transformsWithOnePath](https://github.com/svg/svgo/blob/master/plugins/transformsWithOnePath.js) | apply transforms, crop by real width, center vertical alignment, and resize SVG with one Path inside (disabled by default) |
|
||||
| [removeDimensions](https://github.com/svg/svgo/blob/master/plugins/removeDimensions.js) | remove `width`/`height` attributes if `viewBox` is present (disabled by default) |
|
||||
| [removeDimensions](https://github.com/svg/svgo/blob/master/plugins/removeDimensions.js) | remove `width`/`height` attributes if `viewBox` is present (opposite to removeViewBox, disable it first) (disabled by default) |
|
||||
| [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) |
|
||||
|
||||
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))
|
||||
|
||||
|
||||
## How to use
|
||||
## Installation
|
||||
|
||||
```sh
|
||||
$ [sudo] npm install -g svgo
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### <abbr title="Command Line Interface">CLI</abbr>
|
||||
|
||||
```
|
||||
Usage:
|
||||
svgo [OPTIONS] [ARGS]
|
||||
@@ -85,60 +94,95 @@ Options:
|
||||
-o OUTPUT, --output=OUTPUT : Output file or folder (by default the same as the input), "-" for STDOUT
|
||||
-p PRECISION, --precision=PRECISION : Set number of digits in the fractional part, overrides plugins params
|
||||
--config=CONFIG : Config file or JSON string to extend or replace default
|
||||
--disable=DISABLE : Disable plugin by name
|
||||
--enable=ENABLE : Enable plugin by name
|
||||
--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)
|
||||
--multipass : Enable multipass
|
||||
--pretty : Make SVG pretty printed
|
||||
--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
|
||||
--show-plugins : Show available plugins and exit
|
||||
|
||||
Arguments:
|
||||
INPUT : Alias to --input
|
||||
OUTPUT : Alias to --output
|
||||
```
|
||||
|
||||
* with files:
|
||||
|
||||
$ svgo test.svg
|
||||
```sh
|
||||
$ svgo test.svg
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
$ svgo test.svg test.min.svg
|
||||
```sh
|
||||
$ svgo *.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg -o test.min.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg -o test.min.svg -o other.min.svg -o third.min.svg
|
||||
```
|
||||
|
||||
* with STDIN / STDOUT:
|
||||
|
||||
$ cat test.svg | svgo -i - -o - > test.min.svg
|
||||
```sh
|
||||
$ cat test.svg | svgo -i - -o - > test.min.svg
|
||||
```
|
||||
|
||||
* with folder
|
||||
|
||||
$ svgo -f ../path/to/folder/with/svg/files
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files
|
||||
```
|
||||
|
||||
or:
|
||||
|
||||
$ svgo -f ../path/to/folder/with/svg/files -o ../path/to/folder/with/svg/output
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo *.svg -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
* with strings:
|
||||
|
||||
$ svgo -s '<svg version="1.1">test</svg>' -o test.min.svg
|
||||
```sh
|
||||
$ svgo -s '<svg version="1.1">test</svg>' -o test.min.svg
|
||||
```
|
||||
|
||||
or even with Data URI base64:
|
||||
|
||||
$ svgo -s 'data:image/svg+xml;base64,…' -o test.min.svg
|
||||
```sh
|
||||
$ svgo -s 'data:image/svg+xml;base64,...' -o test.min.svg
|
||||
```
|
||||
|
||||
* with SVGZ:
|
||||
|
||||
from `.svgz` to `.svg`:
|
||||
|
||||
$ gunzip -c test.svgz | svgo -i - -o test.min.svg
|
||||
```sh
|
||||
$ gunzip -c test.svgz | svgo -i - -o test.min.svg
|
||||
```
|
||||
|
||||
from `.svg` to `.svgz`:
|
||||
|
||||
$ svgo test.svg -o - | gzip -cfq9 > test.svgz
|
||||
```sh
|
||||
$ svgo test.svg -o - | gzip -cfq9 > test.svgz
|
||||
```
|
||||
|
||||
* with GUI – [svgo-gui](https://github.com/svg/svgo-gui)
|
||||
* as a web app - [SVGOMG](https://jakearchibald.github.io/svgomg/)
|
||||
### Other Ways to Use SVGO
|
||||
|
||||
* as a web app – [SVGOMG](https://jakearchibald.github.io/svgomg/)
|
||||
* as a Nodejs module – [examples](https://github.com/svg/svgo/tree/master/examples)
|
||||
* as a Grunt task – [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)
|
||||
* as a Gulp task – [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin)
|
||||
@@ -146,9 +190,13 @@ Arguments:
|
||||
* as an OSX Folder Action – [svgo-osx-folder-action](https://github.com/svg/svgo-osx-folder-action)
|
||||
* as a webpack loader – [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader)
|
||||
* as a Telegram Bot – [svgo_bot](https://github.com/maksugr/svgo_bot)
|
||||
* as a PostCSS plugin - [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
|
||||
* as a PostCSS plugin – [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
|
||||
* as an Inkscape plugin – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
|
||||
* as a Sketch plugin - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
|
||||
* as macOS app - [Image Shrinker](https://image-shrinker.com)
|
||||
* as a Rollup plugin - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)
|
||||
|
||||
## License and copyrights
|
||||
## License and Copyright
|
||||
|
||||
This software is released under the terms of the [MIT license](https://github.com/svg/svgo/blob/master/LICENSE).
|
||||
|
||||
|
||||
98
node_modules/svgo/README.ru.md
generated
vendored
98
node_modules/svgo/README.ru.md
generated
vendored
@@ -3,30 +3,31 @@
|
||||
|
||||
<img src="https://svg.github.io/svgo-logo.svg" width="200" height="200" alt="logo"/>
|
||||
|
||||
## SVGO [](https://npmjs.org/package/svgo) [](https://gemnasium.com/svg/svgo) [](https://travis-ci.org/svg/svgo) [](https://coveralls.io/r/svg/svgo?branch=master)
|
||||
## SVGO [](https://npmjs.org/package/svgo) [](https://travis-ci.org/svg/svgo) [](https://coveralls.io/r/svg/svgo?branch=master)
|
||||
|
||||
**SVG** **O**ptimizer – это инструмент для оптимизации векторной графики в формате SVG, написанный на Node.js.
|
||||

|
||||
|
||||
## Зачем?
|
||||
|
||||
SVG-файлы, особенно – экспортированные из различных редакторов, содержат много избыточной и бесполезной информации, комментариев, скрытых элементов, неоптимальные или стандартные значения и другой мусор, удаление которого безопасно и не влияет на конечный результат отрисовки.
|
||||
SVG-файлы, особенно экспортированные из редакторов, содержат много избыточной и бесполезной информации, комментариев, скрытых элементов, неоптимальные или стандартные значения и другой мусор, удаление которого безопасно и не влияет на конечный вид изображения.
|
||||
|
||||
## Возможности
|
||||
|
||||
SVGO имеет расширяемую архитектуру, в которой почти каждая оптимизация является отдельным расширением.
|
||||
|
||||
Сегодня у нас есть:
|
||||
Что у нас есть:
|
||||
|
||||
| Plugin | Description |
|
||||
| ------ | ----------- |
|
||||
| ------ | ----------- |
|
||||
| [cleanupAttrs](https://github.com/svg/svgo/blob/master/plugins/cleanupAttrs.js) | удаление переносов строк и лишних пробелов |
|
||||
| [inlineStyles](https://github.com/svg/svgo/blob/master/plugins/inlineStyles.js) | перенос стилей из элементов `<style>` в атрибуты `style` |
|
||||
| [removeDoctype](https://github.com/svg/svgo/blob/master/plugins/removeDoctype.js) | удаление doctype |
|
||||
| [removeXMLProcInst](https://github.com/svg/svgo/blob/master/plugins/removeXMLProcInst.js) | удаление XML-инструкций |
|
||||
| [removeComments](https://github.com/svg/svgo/blob/master/plugins/removeComments.js) | удаление комментариев |
|
||||
| [removeMetadata](https://github.com/svg/svgo/blob/master/plugins/removeMetadata.js) | удаление `<metadata>` |
|
||||
| [removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) | удаление `<title>` (выключено по умолчанию) |
|
||||
| [removeDesc](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) | удаление `<desc>` (по умолчанию только незначимых) |
|
||||
| [removeTitle](https://github.com/svg/svgo/blob/master/plugins/removeTitle.js) | удаление `<title>` |
|
||||
| [removeDesc](https://github.com/svg/svgo/blob/master/plugins/removeDesc.js) | удаление `<desc>` |
|
||||
| [removeUselessDefs](https://github.com/svg/svgo/blob/master/plugins/removeUselessDefs.js) | удаление элементов в `<defs>` без `id` |
|
||||
| [removeXMLNS](https://github.com/svg/svgo/blob/master/plugins/removeXMLNS.js) | удаление атрибута xmlns (для заинлайненных svg, выключено по умолчанию) |
|
||||
| [removeEditorsNSData](https://github.com/svg/svgo/blob/master/plugins/removeEditorsNSData.js) | удаление пространств имён различных редакторов, их элементов и атрибутов |
|
||||
@@ -45,25 +46,29 @@ SVGO имеет расширяемую архитектуру, в которой
|
||||
| [removeNonInheritableGroupAttrs](https://github.com/svg/svgo/blob/master/plugins/removeNonInheritableGroupAttrs.js) | удаление ненаследуемых "презентационных" атрибутов групп |
|
||||
| [removeUselessStrokeAndFill](https://github.com/svg/svgo/blob/master/plugins/removeUselessStrokeAndFill.js) | удаление неиспользуемых атрибутов stroke-* и fill-* |
|
||||
| [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 |
|
||||
| [cleanupNumericValues](https://github.com/svg/svgo/blob/master/plugins/cleanupNumericValues.js) | округление дробных чисел до заданной точности, удаление `px` как единицы |измерения по-умолчанию
|
||||
| [cleanupListOfValues](https://github.com/svg/svgo/blob/master/plugins/cleanupListOfValues.js) | округление числовых значений в атрибутах со списком чисел, таких как `viewBox` |или `enableBackground`
|
||||
| [moveElemsAttrsToGroup](https://github.com/svg/svgo/blob/master/plugins/moveElemsAttrsToGroup.js) | перемещение совпадающих атрибутов у всех элементов внутри группы `<g>` |
|
||||
| [moveGroupAttrsToElems](https://github.com/svg/svgo/blob/master/plugins/moveGroupAttrsToElems.js) | перемещение некоторых атрибутов группы на элементы внутри |
|
||||
| [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 в одну кривую |
|
||||
| [convertShapeToPath](https://github.com/svg/svgo/blob/master/plugins/convertShapeToPath.js) | конвертирование простых форм в Path |
|
||||
| [sortAttrs](https://github.com/svg/svgo/blob/master/plugins/sortAttrs.js) | сортировка атрибутов элементов для удобочитаемости (выключено по умолчанию) |
|
||||
| [transformsWithOnePath](https://github.com/svg/svgo/blob/master/plugins/transformsWithOnePath.js) | применение трансформаций, обрезка по реальной ширине, вертикальное |выравнивание по центру и изменение размеров SVG с одним Path внутри
|
||||
| [removeDimensions](https://github.com/svg/svgo/blob/master/plugins/removeDimensions.js) | удаляет атрибуты width/height при наличии viewBox (выключено по умолчанию) |
|
||||
| [removeDimensions](https://github.com/svg/svgo/blob/master/plugins/removeDimensions.js) | удаляет атрибуты width/height при наличии viewBox (противоречит removeViewBox — плагин должен быть выключен) (выключено по умолчанию) |
|
||||
| [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> (выключено по умолчанию) |
|
||||
|
||||
Хотите узнать, как это работает и как написать свой плагин? [Конечно же, да!](https://github.com/svg/svgo/blob/master/docs/how-it-works/ru.md).
|
||||
Хотите узнать принципы работы и как написать свой плагин? [Конечно же, да!](https://github.com/svg/svgo/blob/master/docs/how-it-works/ru.md)
|
||||
|
||||
|
||||
## Как использовать
|
||||
@@ -72,8 +77,12 @@ SVGO имеет расширяемую архитектуру, в которой
|
||||
$ [sudo] npm install -g svgo
|
||||
```
|
||||
|
||||
## Выполнение:
|
||||
|
||||
### Командная строка
|
||||
|
||||
```
|
||||
Выполнение:
|
||||
Запуск:
|
||||
svgo [OPTIONS] [ARGS]
|
||||
|
||||
Параметры:
|
||||
@@ -85,68 +94,107 @@ $ [sudo] npm install -g svgo
|
||||
-o OUTPUT, --output=OUTPUT : Выходной файл или папка (совпадает с входным по умолчанию), "-" для STDOUT
|
||||
-p PRECISION, --precision=PRECISION : Число цифр после запятой, переопределяет параметры плагинов
|
||||
--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)
|
||||
--multipass : Оптимизация в несколько проходов
|
||||
--pretty : Удобочитаемое форматирование SVG
|
||||
--indent=INDENT : Размер отступа для удобочитаемого форматирования
|
||||
-r, --recursive : Совместно с '-f'. Рекурсивно обрабатывать *.svg файлы в папках.
|
||||
-q, --quiet : Подавляет вывод информации, выводятся только сообщения об ошибках
|
||||
--show-plugins : Доступные плагины
|
||||
|
||||
Аргументы:
|
||||
INPUT : Аналогично --input
|
||||
OUTPUT : Аналогично --output
|
||||
```
|
||||
|
||||
* с файлами:
|
||||
|
||||
$ svgo test.svg
|
||||
```sh
|
||||
$ svgo test.svg
|
||||
```
|
||||
|
||||
или:
|
||||
|
||||
$ svgo test.svg test.min.svg
|
||||
```sh
|
||||
$ svgo *.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg -o test.min.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo test.svg other.svg third.svg -o test.min.svg -o other.min.svg -o third.min.svg
|
||||
```
|
||||
|
||||
* со STDIN / STDOUT:
|
||||
|
||||
$ cat test.svg | svgo -i - -o - > test.min.svg
|
||||
```sh
|
||||
$ cat test.svg | svgo -i - -o - > test.min.svg
|
||||
```
|
||||
|
||||
* с папками
|
||||
|
||||
$ svgo -f ../path/to/folder/with/svg/files
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files
|
||||
```
|
||||
|
||||
или:
|
||||
|
||||
$ svgo -f ../path/to/folder/with/svg/files -o ../path/to/folder/with/svg/output
|
||||
```sh
|
||||
$ svgo -f ../path/to/folder/with/svg/files -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
```sh
|
||||
$ svgo *.svg -o ../path/to/folder/with/svg/output
|
||||
```
|
||||
|
||||
* со строками:
|
||||
|
||||
$ svgo -s '<svg version="1.1">test</svg>' -o test.min.svg
|
||||
```sh
|
||||
$ svgo -s '<svg version="1.1">test</svg>' -o test.min.svg
|
||||
```
|
||||
|
||||
или даже с Data URI base64:
|
||||
|
||||
$ svgo -s 'data:image/svg+xml;base64,…' -o test.min.svg
|
||||
```sh
|
||||
$ svgo -s 'data:image/svg+xml;base64,…' -o test.min.svg
|
||||
```
|
||||
|
||||
* с SVGZ:
|
||||
|
||||
из `.svgz` в `.svg`:
|
||||
|
||||
$ gunzip -c test.svgz | svgo -i - -o test.min.svg
|
||||
```sh
|
||||
$ gunzip -c test.svgz | svgo -i - -o test.min.svg
|
||||
```
|
||||
|
||||
из `.svg` в `.svgz`:
|
||||
|
||||
$ svgo test.svg -o - | gzip -cfq9 > test.svgz
|
||||
```sh
|
||||
$ svgo test.svg -o - | gzip -cfq9 > test.svgz
|
||||
```
|
||||
|
||||
### Другие способы использования SVGO
|
||||
|
||||
* с помощью GUI – [svgo-gui](https://github.com/svg/svgo-gui)
|
||||
* в виде веб-приложения - [SVGOMG](https://jakearchibald.github.io/svgomg/)
|
||||
* как модуль Node.js – [examples](https://github.com/svg/svgo/tree/master/examples)
|
||||
* как таск для Grunt – [grunt-svgmin](https://github.com/sindresorhus/grunt-svgmin)
|
||||
* как таск для Gulp – [gulp-svgmin](https://github.com/ben-eb/gulp-svgmin)
|
||||
* как таск для Mimosa – [mimosa-minify-svg](https://github.com/dbashford/mimosa-minify-svg)
|
||||
* как действие папки в OSX – [svgo-osx-folder-action](https://github.com/svg/svgo-osx-folder-action)
|
||||
* через загрузчик в webpack – [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader)
|
||||
* через загрузчик webpack – [image-webpack-loader](https://github.com/tcoopman/image-webpack-loader)
|
||||
* с помощью бота в Telegram – [svgo_bot](https://github.com/maksugr/svgo_bot)
|
||||
* как плагин PostCSS - [postcss-svgo](https://github.com/ben-eb/postcss-svgo)
|
||||
* как плагин для Inkscape – [inkscape-svgo](https://github.com/konsumer/inkscape-svgo)
|
||||
* как плагин для Sketch - [svgo-compressor](https://github.com/BohemianCoding/svgo-compressor)
|
||||
* в виде приложения macOS - [Image Shrinker](https://image-shrinker.com)
|
||||
* как плагин для Rollup - [rollup-plugin-svgo](https://github.com/porsager/rollup-plugin-svgo)
|
||||
|
||||
## Лицензия и копирайты
|
||||
|
||||
|
||||
70
node_modules/svgo/lib/svgo.js
generated
vendored
70
node_modules/svgo/lib/svgo.js
generated
vendored
@@ -14,56 +14,60 @@ var CONFIG = require('./svgo/config.js'),
|
||||
SVG2JS = require('./svgo/svg2js.js'),
|
||||
PLUGINS = require('./svgo/plugins.js'),
|
||||
JSAPI = require('./svgo/jsAPI.js'),
|
||||
encodeSVGDatauri = require('./svgo/tools.js').encodeSVGDatauri,
|
||||
JS2SVG = require('./svgo/js2svg.js');
|
||||
|
||||
var SVGO = module.exports = function(config) {
|
||||
|
||||
var SVGO = function(config) {
|
||||
this.config = CONFIG(config);
|
||||
|
||||
};
|
||||
|
||||
SVGO.prototype.optimize = function(svgstr, callback) {
|
||||
if (this.config.error) return callback(this.config);
|
||||
SVGO.prototype.optimize = function(svgstr, info) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (this.config.error) {
|
||||
reject(this.config.error);
|
||||
return;
|
||||
}
|
||||
|
||||
var _this = this,
|
||||
config = this.config,
|
||||
maxPassCount = config.multipass ? 10 : 1,
|
||||
counter = 0,
|
||||
prevResultSize = Number.POSITIVE_INFINITY,
|
||||
optimizeOnceCallback = function(svgjs) {
|
||||
var config = this.config,
|
||||
maxPassCount = config.multipass ? 10 : 1,
|
||||
counter = 0,
|
||||
prevResultSize = Number.POSITIVE_INFINITY,
|
||||
optimizeOnceCallback = (svgjs) => {
|
||||
if (svgjs.error) {
|
||||
reject(svgjs.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (svgjs.error) {
|
||||
callback(svgjs);
|
||||
return;
|
||||
}
|
||||
|
||||
if (++counter < maxPassCount && svgjs.data.length < prevResultSize) {
|
||||
prevResultSize = svgjs.data.length;
|
||||
_this._optimizeOnce(svgjs.data, optimizeOnceCallback);
|
||||
} else {
|
||||
callback(svgjs);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
_this._optimizeOnce(svgstr, optimizeOnceCallback);
|
||||
if (++counter < maxPassCount && svgjs.data.length < prevResultSize) {
|
||||
prevResultSize = svgjs.data.length;
|
||||
this._optimizeOnce(svgjs.data, info, optimizeOnceCallback);
|
||||
} else {
|
||||
if (config.datauri) {
|
||||
svgjs.data = encodeSVGDatauri(svgjs.data, config.datauri);
|
||||
}
|
||||
if (info && info.path) {
|
||||
svgjs.path = info.path;
|
||||
}
|
||||
resolve(svgjs);
|
||||
}
|
||||
};
|
||||
|
||||
this._optimizeOnce(svgstr, info, optimizeOnceCallback);
|
||||
});
|
||||
};
|
||||
|
||||
SVGO.prototype._optimizeOnce = function(svgstr, callback) {
|
||||
SVGO.prototype._optimizeOnce = function(svgstr, info, callback) {
|
||||
var config = this.config;
|
||||
|
||||
SVG2JS(svgstr, function(svgjs) {
|
||||
|
||||
if (svgjs.error) {
|
||||
callback(svgjs);
|
||||
return;
|
||||
}
|
||||
|
||||
svgjs = PLUGINS(svgjs, config.plugins);
|
||||
svgjs = PLUGINS(svgjs, info, config.plugins);
|
||||
|
||||
callback(JS2SVG(svgjs, config.js2svg));
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
@@ -74,7 +78,9 @@ SVGO.prototype._optimizeOnce = function(svgstr, callback) {
|
||||
* @returns {JSAPI} content item
|
||||
*/
|
||||
SVGO.prototype.createContentItem = function(data) {
|
||||
|
||||
return new JSAPI(data);
|
||||
|
||||
};
|
||||
|
||||
module.exports = SVGO;
|
||||
// Offer ES module interop compatibility.
|
||||
module.exports.default = SVGO;
|
||||
|
||||
613
node_modules/svgo/lib/svgo/coa.js
generated
vendored
613
node_modules/svgo/lib/svgo/coa.js
generated
vendored
@@ -1,17 +1,23 @@
|
||||
/* jshint quotmark: false */
|
||||
'use strict';
|
||||
|
||||
require('colors');
|
||||
|
||||
var FS = require('fs'),
|
||||
PATH = require('path'),
|
||||
chalk = require('chalk'),
|
||||
mkdirp = require('mkdirp'),
|
||||
promisify = require('util.promisify'),
|
||||
readdir = promisify(FS.readdir),
|
||||
readFile = promisify(FS.readFile),
|
||||
writeFile = promisify(FS.writeFile),
|
||||
SVGO = require('../svgo.js'),
|
||||
YAML = require('js-yaml'),
|
||||
PKG = require('../../package.json'),
|
||||
mkdirp = require('mkdirp'),
|
||||
encodeSVGDatauri = require('./tools.js').encodeSVGDatauri,
|
||||
decodeSVGDatauri = require('./tools.js').decodeSVGDatauri,
|
||||
regSVGFile = /\.svg$/;
|
||||
checkIsDir = require('./tools.js').checkIsDir,
|
||||
regSVGFile = /\.svg$/,
|
||||
noop = () => {},
|
||||
svgo;
|
||||
|
||||
/**
|
||||
* Command-Option-Argument.
|
||||
@@ -37,6 +43,7 @@ module.exports = require('coa').Cmd()
|
||||
.opt()
|
||||
.name('input').title('Input file, "-" for STDIN')
|
||||
.short('i').long('input')
|
||||
.arr()
|
||||
.val(function(val) {
|
||||
return val || this.reject("Option '--input' must have a value.");
|
||||
})
|
||||
@@ -55,6 +62,7 @@ module.exports = require('coa').Cmd()
|
||||
.opt()
|
||||
.name('output').title('Output file or folder (by default the same as the input), "-" for STDOUT')
|
||||
.short('o').long('output')
|
||||
.arr()
|
||||
.val(function(val) {
|
||||
return val || this.reject("Option '--output' must have a value.");
|
||||
})
|
||||
@@ -74,7 +82,7 @@ module.exports = require('coa').Cmd()
|
||||
})
|
||||
.end()
|
||||
.opt()
|
||||
.name('disable').title('Disable plugin by name')
|
||||
.name('disable').title('Disable plugin by name, "--disable={PLUGIN1,PLUGIN2}" for multiple plugins (*nix)')
|
||||
.long('disable')
|
||||
.arr()
|
||||
.val(function(val) {
|
||||
@@ -82,7 +90,7 @@ module.exports = require('coa').Cmd()
|
||||
})
|
||||
.end()
|
||||
.opt()
|
||||
.name('enable').title('Enable plugin by name')
|
||||
.name('enable').title('Enable plugin by name, "--enable={PLUGIN3,PLUGIN4}" for multiple plugins (*nix)')
|
||||
.long('enable')
|
||||
.arr()
|
||||
.val(function(val) {
|
||||
@@ -113,6 +121,11 @@ module.exports = require('coa').Cmd()
|
||||
return !isNaN(val) ? val : this.reject("Option '--indent' must be an integer number");
|
||||
})
|
||||
.end()
|
||||
.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')
|
||||
.short('q').long('quiet')
|
||||
@@ -125,70 +138,65 @@ module.exports = require('coa').Cmd()
|
||||
.end()
|
||||
.arg()
|
||||
.name('input').title('Alias to --input')
|
||||
.end()
|
||||
.arg()
|
||||
.name('output').title('Alias to --output')
|
||||
.arr()
|
||||
.end()
|
||||
.act(function(opts, args) {
|
||||
|
||||
var input = args && args.input ? args.input : opts.input,
|
||||
output = args && args.output ? args.output : opts.output,
|
||||
var input = opts.input || args.input,
|
||||
output = opts.output,
|
||||
config = {};
|
||||
|
||||
// --show-plugins
|
||||
if (opts['show-plugins']) {
|
||||
|
||||
showAvailablePlugins();
|
||||
process.exit(0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// w/o anything
|
||||
if (
|
||||
(!input || input === '-') &&
|
||||
(!input || input[0] === '-') &&
|
||||
!opts.string &&
|
||||
!opts.stdin &&
|
||||
!opts.folder &&
|
||||
process.stdin.isTTY
|
||||
process.stdin.isTTY === true
|
||||
) return this.usage();
|
||||
|
||||
if (typeof process == 'object' && process.versions && process.versions.node && PKG && PKG.engines.node) {
|
||||
var nodeVersion = String(PKG.engines.node).match(/\d*(\.\d+)*/)[0];
|
||||
if (parseFloat(process.versions.node) < parseFloat(nodeVersion)) {
|
||||
return printErrorAndExit(`Error: ${PKG.name} requires Node.js version ${nodeVersion} or higher.`);
|
||||
}
|
||||
}
|
||||
|
||||
// --config
|
||||
if (opts.config) {
|
||||
|
||||
// string
|
||||
if (opts.config.charAt(0) === '{') {
|
||||
try {
|
||||
config = JSON.parse(opts.config);
|
||||
} catch (e) {
|
||||
console.error("Error: Couldn't parse config JSON.");
|
||||
console.error(String(e));
|
||||
return;
|
||||
return printErrorAndExit(`Error: Couldn't parse config JSON.\n${String(e)}`);
|
||||
}
|
||||
|
||||
// external file
|
||||
} else {
|
||||
var configPath = PATH.resolve(opts.config);
|
||||
var configPath = PATH.resolve(opts.config),
|
||||
configData;
|
||||
try {
|
||||
// require() adds some weird output on YML files
|
||||
config = JSON.parse(FS.readFileSync(configPath, 'utf8'));
|
||||
configData = FS.readFileSync(configPath, 'utf8');
|
||||
config = JSON.parse(configData);
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
console.error('Error: couldn\'t find config file \'' + opts.config + '\'.');
|
||||
return;
|
||||
return printErrorAndExit(`Error: couldn't find config file '${opts.config}'.`);
|
||||
} else if (err.code === 'EISDIR') {
|
||||
console.error('Error: directory \'' + opts.config + '\' is not a config file.');
|
||||
return;
|
||||
return printErrorAndExit(`Error: directory '${opts.config}' is not a config file.`);
|
||||
}
|
||||
config = YAML.safeLoad(FS.readFileSync(configPath, 'utf8'));
|
||||
config = YAML.safeLoad(configData);
|
||||
|
||||
if (!config || Array.isArray(config)) {
|
||||
console.error('Error: invalid config file \'' + opts.config + '\'.');
|
||||
return;
|
||||
return printErrorAndExit(`Error: invalid config file '${opts.config}'.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// --quiet
|
||||
@@ -196,9 +204,17 @@ module.exports = require('coa').Cmd()
|
||||
config.quiet = opts.quiet;
|
||||
}
|
||||
|
||||
// --recursive
|
||||
if (opts.recursive) {
|
||||
config.recursive = opts.recursive;
|
||||
}
|
||||
|
||||
// --precision
|
||||
if (opts.precision) {
|
||||
config.floatPrecision = Math.max(0, parseInt(opts.precision));
|
||||
var precision = Math.min(Math.max(0, parseInt(opts.precision)), 20);
|
||||
if (!isNaN(precision)) {
|
||||
config.floatPrecision = precision;
|
||||
}
|
||||
}
|
||||
|
||||
// --disable
|
||||
@@ -213,163 +229,75 @@ module.exports = require('coa').Cmd()
|
||||
|
||||
// --multipass
|
||||
if (opts.multipass) {
|
||||
|
||||
config.multipass = true;
|
||||
|
||||
}
|
||||
|
||||
// --pretty
|
||||
if (opts.pretty) {
|
||||
|
||||
config.js2svg = config.js2svg || {};
|
||||
config.js2svg.pretty = true;
|
||||
if (opts.indent) {
|
||||
config.js2svg.indent = parseInt(opts.indent, 10);
|
||||
var indent;
|
||||
if (opts.indent && !isNaN(indent = parseInt(opts.indent))) {
|
||||
config.js2svg.indent = indent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
svgo = new SVGO(config);
|
||||
|
||||
// --output
|
||||
if (opts.output) {
|
||||
config.output = opts.output;
|
||||
if (output) {
|
||||
if (input && input[0] != '-') {
|
||||
if (output.length == 1 && checkIsDir(output[0])) {
|
||||
var dir = output[0];
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
output[i] = checkIsDir(input[i]) ? input[i] : PATH.resolve(dir, PATH.basename(input[i]));
|
||||
}
|
||||
} else if (output.length < input.length) {
|
||||
output = output.concat(input.slice(output.length));
|
||||
}
|
||||
}
|
||||
} else if (input) {
|
||||
output = input;
|
||||
} else if (opts.string) {
|
||||
output = '-';
|
||||
}
|
||||
|
||||
if (opts.datauri) {
|
||||
config.datauri = opts.datauri;
|
||||
}
|
||||
|
||||
// --folder
|
||||
if (opts.folder) {
|
||||
optimizeFolder(opts.folder, config, output);
|
||||
|
||||
return;
|
||||
var ouputFolder = output && output[0] || opts.folder;
|
||||
return optimizeFolder(config, opts.folder, ouputFolder).then(noop, printErrorAndExit);
|
||||
}
|
||||
|
||||
// --input
|
||||
if (input) {
|
||||
|
||||
// STDIN
|
||||
if (input === '-') {
|
||||
|
||||
var data = '';
|
||||
|
||||
process.stdin.pause();
|
||||
|
||||
process.stdin
|
||||
.on('data', function(chunk) {
|
||||
data += chunk;
|
||||
})
|
||||
.once('end', function() {
|
||||
optimizeFromString(data, config, opts.datauri, input, output);
|
||||
})
|
||||
.resume();
|
||||
if (input[0] === '-') {
|
||||
return new Promise((resolve, reject) => {
|
||||
var data = '',
|
||||
file = output[0];
|
||||
|
||||
process.stdin
|
||||
.on('data', chunk => data += chunk)
|
||||
.once('end', () => processSVGData(config, {input: 'string'}, data, file).then(resolve, reject));
|
||||
});
|
||||
// file
|
||||
} else {
|
||||
|
||||
FS.readFile(input, 'utf8', function(err, data) {
|
||||
if (err) {
|
||||
if (err.code === 'EISDIR')
|
||||
optimizeFolder(input, config, output);
|
||||
else if (err.code === 'ENOENT')
|
||||
console.error('Error: no such file or directory \'' + input + '\'.');
|
||||
else
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
optimizeFromString(data, config, opts.datauri, input, output);
|
||||
});
|
||||
|
||||
return Promise.all(input.map((file, n) => optimizeFile(config, file, output[n])))
|
||||
.then(noop, printErrorAndExit);
|
||||
}
|
||||
|
||||
// --string
|
||||
} else if (opts.string) {
|
||||
var data = decodeSVGDatauri(opts.string);
|
||||
|
||||
opts.string = decodeSVGDatauri(opts.string);
|
||||
|
||||
optimizeFromString(opts.string, config, opts.datauri, input, output);
|
||||
|
||||
return processSVGData(config, {input: 'string'}, data, output[0]);
|
||||
}
|
||||
});
|
||||
|
||||
function optimizeFromString(svgstr, config, datauri, input, output) {
|
||||
|
||||
var startTime = Date.now(config),
|
||||
time,
|
||||
inBytes = Buffer.byteLength(svgstr, 'utf8'),
|
||||
outBytes,
|
||||
svgo = new SVGO(config);
|
||||
|
||||
svgo.optimize(svgstr, function(result) {
|
||||
|
||||
if (result.error) {
|
||||
console.error(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
if (datauri) {
|
||||
result.data = encodeSVGDatauri(result.data, datauri);
|
||||
}
|
||||
|
||||
outBytes = Buffer.byteLength(result.data, 'utf8');
|
||||
time = Date.now() - startTime;
|
||||
|
||||
// stdout
|
||||
if (output === '-' || (!input || input === '-') && !output) {
|
||||
|
||||
process.stdout.write(result.data + '\n');
|
||||
|
||||
// file
|
||||
} else {
|
||||
|
||||
// overwrite input file if there is no output
|
||||
if (!output && input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
if (!config.quiet) {
|
||||
console.log('\r');
|
||||
}
|
||||
|
||||
saveFileAndPrintInfo(config, result.data, output, inBytes, outBytes, time);
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function saveFileAndPrintInfo(config, data, path, inBytes, outBytes, time) {
|
||||
|
||||
FS.writeFile(path, data, 'utf8', function() {
|
||||
if (config.quiet) {
|
||||
return;
|
||||
}
|
||||
|
||||
// print time info
|
||||
printTimeInfo(time);
|
||||
|
||||
// print optimization profit info
|
||||
printProfitInfo(inBytes, outBytes);
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function printTimeInfo(time) {
|
||||
console.log('Done in ' + time + ' ms!');
|
||||
|
||||
}
|
||||
|
||||
function printProfitInfo(inBytes, outBytes) {
|
||||
|
||||
var profitPercents = 100 - outBytes * 100 / inBytes;
|
||||
|
||||
console.log(
|
||||
(Math.round((inBytes / 1024) * 1000) / 1000) + ' KiB' +
|
||||
(profitPercents < 0 ? ' + ' : ' - ') +
|
||||
String(Math.abs((Math.round(profitPercents * 10) / 10)) + '%').green + ' = ' +
|
||||
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB\n'
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change plugins state by names array.
|
||||
*
|
||||
@@ -379,17 +307,15 @@ function printProfitInfo(inBytes, outBytes) {
|
||||
* @return {Object} changed config
|
||||
*/
|
||||
function changePluginsState(names, state, config) {
|
||||
names.forEach(flattenPluginsCbk);
|
||||
|
||||
// extend config
|
||||
if (config.plugins) {
|
||||
|
||||
names.forEach(function(name) {
|
||||
|
||||
var matched,
|
||||
for (var name of names) {
|
||||
var matched = false,
|
||||
key;
|
||||
|
||||
config.plugins.forEach(function(plugin) {
|
||||
|
||||
for (var plugin of config.plugins) {
|
||||
// get plugin name
|
||||
if (typeof plugin === 'object') {
|
||||
key = Object.keys(plugin)[0];
|
||||
@@ -403,179 +329,250 @@ function changePluginsState(names, state, config) {
|
||||
if (typeof plugin[key] !== 'object' || !state) {
|
||||
plugin[key] = state;
|
||||
}
|
||||
|
||||
// mark it as matched
|
||||
matched = true;
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
// if not matched and current config is not full
|
||||
if (!matched && !config.full) {
|
||||
|
||||
var obj = {};
|
||||
|
||||
obj[name] = state;
|
||||
|
||||
// push new plugin Object
|
||||
config.plugins.push(obj);
|
||||
|
||||
config.plugins.push({ [name]: state });
|
||||
matched = true;
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
// just push
|
||||
} else {
|
||||
|
||||
config.plugins = [];
|
||||
|
||||
names.forEach(function(name) {
|
||||
var obj = {};
|
||||
|
||||
obj[name] = state;
|
||||
|
||||
config.plugins.push(obj);
|
||||
});
|
||||
|
||||
config.plugins = names.map(name => ({ [name]: state }));
|
||||
}
|
||||
|
||||
return config;
|
||||
|
||||
}
|
||||
|
||||
function optimizeFolder(dir, config, output) {
|
||||
/**
|
||||
* 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(',');
|
||||
|
||||
var svgo = new SVGO(config);
|
||||
|
||||
if (!config.quiet) {
|
||||
console.log('Processing directory \'' + dir + '\':\n');
|
||||
if(split.length > 1) {
|
||||
names[index] = split.shift();
|
||||
names.push.apply(names, split);
|
||||
}
|
||||
|
||||
// absoluted folder path
|
||||
var path = PATH.resolve(dir);
|
||||
}
|
||||
|
||||
// list folder content
|
||||
FS.readdir(path, function(err, files) {
|
||||
/**
|
||||
* Optimize SVG files in a directory.
|
||||
* @param {Object} config options
|
||||
* @param {string} dir input directory
|
||||
* @param {string} output output directory
|
||||
* @return {Promise}
|
||||
*/
|
||||
function optimizeFolder(config, dir, output) {
|
||||
if (!config.quiet) {
|
||||
console.log(`Processing directory '${dir}':\n`);
|
||||
}
|
||||
return readdir(dir).then(files => processDirectory(config, dir, files, output));
|
||||
}
|
||||
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
/**
|
||||
* Process given files, take only SVG.
|
||||
* @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 {Promise}
|
||||
*/
|
||||
function processDirectory(config, dir, files, output) {
|
||||
// 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.`));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @param {Object} config options
|
||||
* @param {string} file
|
||||
* @param {string} output
|
||||
* @return {Promise}
|
||||
*/
|
||||
function optimizeFile(config, file, output) {
|
||||
return readFile(file, 'utf8').then(
|
||||
data => processSVGData(config, {input: 'file', path: file}, data, output, file),
|
||||
error => checkOptimizeFileError(config, file, output, error)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Optimize SVG data.
|
||||
* @param {Object} config options
|
||||
* @param {string} data SVG content to optimize
|
||||
* @param {string} output where to write optimized file
|
||||
* @param {string} [input] input file name (being used if output is a directory)
|
||||
* @return {Promise}
|
||||
*/
|
||||
function processSVGData(config, info, data, output, input) {
|
||||
var startTime = Date.now(),
|
||||
prevFileSize = Buffer.byteLength(data, 'utf8');
|
||||
|
||||
return svgo.optimize(data, info).then(function(result) {
|
||||
if (config.datauri) {
|
||||
result.data = encodeSVGDatauri(result.data, config.datauri);
|
||||
}
|
||||
var resultFileSize = Buffer.byteLength(result.data, 'utf8'),
|
||||
processingTime = Date.now() - startTime;
|
||||
|
||||
if (!files.length) {
|
||||
console.log('Directory \'' + dir + '\' is empty.');
|
||||
return;
|
||||
}
|
||||
|
||||
var i = 0,
|
||||
found = false;
|
||||
|
||||
function optimizeFile(file) {
|
||||
|
||||
// absoluted file path
|
||||
var filepath = PATH.resolve(path, file);
|
||||
var outfilepath = output ? PATH.resolve(output, file) : filepath;
|
||||
|
||||
// check if file name matches *.svg
|
||||
if (regSVGFile.test(filepath)) {
|
||||
|
||||
found = true;
|
||||
FS.readFile(filepath, 'utf8', function(err, data) {
|
||||
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var startTime = Date.now(),
|
||||
time,
|
||||
inBytes = Buffer.byteLength(data, 'utf8'),
|
||||
outBytes;
|
||||
|
||||
svgo.optimize(data, function(result) {
|
||||
|
||||
if (result.error) {
|
||||
console.error(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
outBytes = Buffer.byteLength(result.data, 'utf8');
|
||||
time = Date.now() - startTime;
|
||||
|
||||
writeOutput();
|
||||
|
||||
function writeOutput() {
|
||||
FS.writeFile(outfilepath, result.data, 'utf8', report);
|
||||
}
|
||||
|
||||
function report(err) {
|
||||
|
||||
if (err) {
|
||||
if (err.code === 'ENOENT') {
|
||||
mkdirp(output, writeOutput);
|
||||
return;
|
||||
} else if (err.code === 'ENOTDIR') {
|
||||
console.error('Error: output \'' + output + '\' is not a directory.');
|
||||
return;
|
||||
}
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!config.quiet) {
|
||||
console.log(file + ':');
|
||||
|
||||
// print time info
|
||||
printTimeInfo(time);
|
||||
|
||||
// print optimization profit info
|
||||
printProfitInfo(inBytes, outBytes);
|
||||
}
|
||||
|
||||
//move on to the next file
|
||||
if (++i < files.length) {
|
||||
optimizeFile(files[i]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
return writeOutput(input, output, result.data).then(function() {
|
||||
if (!config.quiet && output != '-') {
|
||||
if (input) {
|
||||
console.log(`\n${PATH.basename(input)}:`);
|
||||
}
|
||||
printTimeInfo(processingTime);
|
||||
printProfitInfo(prevFileSize, resultFileSize);
|
||||
}
|
||||
//move on to the next file
|
||||
else if (++i < files.length) {
|
||||
optimizeFile(files[i]);
|
||||
} else if (!found) {
|
||||
console.log('No SVG files have been found.');
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
optimizeFile(files[i]);
|
||||
|
||||
},
|
||||
error => Promise.reject(new Error(error.code === 'ENOTDIR' ? `Error: output '${output}' is not a directory.` : error)));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Write result of an optimization.
|
||||
* @param {string} input
|
||||
* @param {string} output output file name. '-' for stdout
|
||||
* @param {string} data data to write
|
||||
* @return {Promise}
|
||||
*/
|
||||
function writeOutput(input, output, data) {
|
||||
if (output == '-') {
|
||||
console.log(data);
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
mkdirp.sync(PATH.dirname(output));
|
||||
|
||||
return writeFile(output, data, 'utf8').catch(error => checkWriteFileError(input, output, data, error));
|
||||
}
|
||||
|
||||
|
||||
var showAvailablePlugins = function () {
|
||||
/**
|
||||
* Write a time taken by optimization.
|
||||
* @param {number} time time in milliseconds.
|
||||
*/
|
||||
function printTimeInfo(time) {
|
||||
console.log(`Done in ${time} ms!`);
|
||||
}
|
||||
|
||||
var svgo = new SVGO(),
|
||||
// Flatten an array of plugins grouped per type and sort alphabetically
|
||||
list = Array.prototype.concat.apply([], svgo.config.plugins).sort(function(a, b) {
|
||||
return a.name > b.name ? 1 : -1;
|
||||
});
|
||||
/**
|
||||
* Write optimizing information in human readable format.
|
||||
* @param {number} inBytes size before optimization.
|
||||
* @param {number} outBytes size after optimization.
|
||||
*/
|
||||
function printProfitInfo(inBytes, outBytes) {
|
||||
var profitPercents = 100 - outBytes * 100 / inBytes;
|
||||
|
||||
console.log(
|
||||
(Math.round((inBytes / 1024) * 1000) / 1000) + ' KiB' +
|
||||
(profitPercents < 0 ? ' + ' : ' - ') +
|
||||
chalk.green(Math.abs((Math.round(profitPercents * 10) / 10)) + '%') + ' = ' +
|
||||
(Math.round((outBytes / 1024) * 1000) / 1000) + ' KiB'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for errors, if it's a dir optimize the dir.
|
||||
* @param {Object} config
|
||||
* @param {string} input
|
||||
* @param {string} output
|
||||
* @param {Error} error
|
||||
* @return {Promise}
|
||||
*/
|
||||
function checkOptimizeFileError(config, input, output, error) {
|
||||
if (error.code == 'EISDIR') {
|
||||
return optimizeFolder(config, input, output);
|
||||
} else if (error.code == 'ENOENT') {
|
||||
return Promise.reject(new Error(`Error: no such file or directory '${error.path}'.`));
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check for saving file error. If the output is a dir, then write file there.
|
||||
* @param {string} input
|
||||
* @param {string} output
|
||||
* @param {string} data
|
||||
* @param {Error} error
|
||||
* @return {Promise}
|
||||
*/
|
||||
function checkWriteFileError(input, output, data, error) {
|
||||
if (error.code == 'EISDIR' && input) {
|
||||
return writeFile(PATH.resolve(output, PATH.basename(input)), data, 'utf8');
|
||||
} else {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show list of available plugins with short description.
|
||||
*/
|
||||
function showAvailablePlugins() {
|
||||
console.log('Currently available plugins:');
|
||||
|
||||
list.forEach(function (plugin) {
|
||||
console.log(' [ ' + plugin.name.green + ' ] ' + plugin.description);
|
||||
});
|
||||
// Flatten an array of plugins grouped per type, sort and write output
|
||||
var list = [].concat.apply([], new SVGO().config.plugins)
|
||||
.sort((a, b) => a.name.localeCompare(b.name))
|
||||
.map(plugin => ` [ ${chalk.green(plugin.name)} ] ${plugin.description}`)
|
||||
.join('\n');
|
||||
console.log(list);
|
||||
}
|
||||
|
||||
//console.log(JSON.stringify(svgo, null, 4));
|
||||
};
|
||||
/**
|
||||
* Write an error and exit.
|
||||
* @param {Error} error
|
||||
* @return {Promise} a promise for running tests
|
||||
*/
|
||||
function printErrorAndExit(error) {
|
||||
console.error(chalk.red(error));
|
||||
process.exit(1);
|
||||
return Promise.reject(error); // for tests
|
||||
}
|
||||
|
||||
22
node_modules/svgo/lib/svgo/config.js
generated
vendored
22
node_modules/svgo/lib/svgo/config.js
generated
vendored
@@ -3,8 +3,6 @@
|
||||
var FS = require('fs');
|
||||
var yaml = require('js-yaml');
|
||||
|
||||
var EXTEND = require('whet.extend');
|
||||
|
||||
/**
|
||||
* Read and/or extend/replace default config file,
|
||||
* prepare and optimize plugins array.
|
||||
@@ -28,8 +26,8 @@ module.exports = function(config) {
|
||||
defaults.plugins = preparePluginsArray(defaults.plugins);
|
||||
}
|
||||
} else {
|
||||
defaults = EXTEND({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));
|
||||
defaults.plugins = preparePluginsArray(defaults.plugins);
|
||||
defaults = Object.assign({}, yaml.safeLoad(FS.readFileSync(__dirname + '/../../.svgo.yml', 'utf8')));
|
||||
defaults.plugins = preparePluginsArray(defaults.plugins || []);
|
||||
defaults = extendConfig(defaults, config);
|
||||
}
|
||||
|
||||
@@ -37,11 +35,15 @@ module.exports = function(config) {
|
||||
defaults.plugins.forEach(function(plugin) {
|
||||
if (plugin.params && ('floatPrecision' in plugin.params)) {
|
||||
// Don't touch default plugin params
|
||||
plugin.params = EXTEND({}, plugin.params, { floatPrecision: config.floatPrecision });
|
||||
plugin.params = Object.assign({}, plugin.params, { floatPrecision: config.floatPrecision });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ('datauri' in config) {
|
||||
defaults.datauri = config.datauri;
|
||||
}
|
||||
|
||||
if (Array.isArray(defaults.plugins)) {
|
||||
defaults.plugins = optimizePluginsArray(defaults.plugins);
|
||||
}
|
||||
@@ -74,11 +76,11 @@ function preparePluginsArray(plugins) {
|
||||
|
||||
} else {
|
||||
|
||||
plugin = EXTEND({}, require('../../plugins/' + key));
|
||||
plugin = Object.assign({}, require('../../plugins/' + key));
|
||||
|
||||
// name: {}
|
||||
if (typeof item[key] === 'object') {
|
||||
plugin.params = EXTEND({}, plugin.params || {}, item[key]);
|
||||
plugin.params = Object.assign({}, plugin.params || {}, item[key]);
|
||||
plugin.active = true;
|
||||
|
||||
// name: false
|
||||
@@ -96,7 +98,7 @@ function preparePluginsArray(plugins) {
|
||||
// name
|
||||
} else {
|
||||
|
||||
plugin = EXTEND({}, require('../../plugins/' + item));
|
||||
plugin = Object.assign({}, require('../../plugins/' + item));
|
||||
plugin.name = item;
|
||||
|
||||
}
|
||||
@@ -138,7 +140,7 @@ function extendConfig(defaults, config) {
|
||||
if (plugin.name === key) {
|
||||
// name: {}
|
||||
if (typeof item[key] === 'object') {
|
||||
plugin.params = EXTEND({}, plugin.params || {}, item[key]);
|
||||
plugin.params = Object.assign({}, plugin.params || {}, item[key]);
|
||||
plugin.active = true;
|
||||
|
||||
// name: false
|
||||
@@ -184,7 +186,7 @@ function extendConfig(defaults, config) {
|
||||
*/
|
||||
function setupCustomPlugin(name, plugin) {
|
||||
plugin.active = true;
|
||||
plugin.params = EXTEND({}, plugin.params || {});
|
||||
plugin.params = Object.assign({}, plugin.params || {});
|
||||
plugin.name = name;
|
||||
|
||||
return plugin;
|
||||
|
||||
12
node_modules/svgo/lib/svgo/js2svg.js
generated
vendored
12
node_modules/svgo/lib/svgo/js2svg.js
generated
vendored
@@ -1,7 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var EOL = require('os').EOL,
|
||||
EXTEND = require('whet.extend'),
|
||||
textElem = require('../../plugins/_collections.js').elemsGroups.textContent.concat('title');
|
||||
|
||||
var defaults = {
|
||||
@@ -56,15 +55,14 @@ module.exports = function(data, config) {
|
||||
function JS2SVG(config) {
|
||||
|
||||
if (config) {
|
||||
this.config = EXTEND(true, {}, defaults, config);
|
||||
this.config = Object.assign({}, defaults, config);
|
||||
} else {
|
||||
this.config = defaults;
|
||||
this.config = Object.assign({}, defaults);
|
||||
}
|
||||
|
||||
var indent = this.config.indent;
|
||||
if (typeof indent == 'number' && !isNaN(indent)) {
|
||||
this.config.indent = '';
|
||||
for (var i = indent; i-- > 0;) this.config.indent += ' ';
|
||||
this.config.indent = (indent < 0) ? '\t' : ' '.repeat(indent);
|
||||
} else if (typeof indent != 'string') {
|
||||
this.config.indent = ' ';
|
||||
}
|
||||
@@ -146,9 +144,7 @@ JS2SVG.prototype.createIndent = function() {
|
||||
var indent = '';
|
||||
|
||||
if (this.config.pretty && !this.textContext) {
|
||||
for (var i = 1; i < this.indentLevel; i++) {
|
||||
indent += this.config.indent;
|
||||
}
|
||||
indent = this.config.indent.repeat(this.indentLevel - 1);
|
||||
}
|
||||
|
||||
return indent;
|
||||
|
||||
86
node_modules/svgo/lib/svgo/jsAPI.js
generated
vendored
86
node_modules/svgo/lib/svgo/jsAPI.js
generated
vendored
@@ -1,9 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
var EXTEND = require('whet.extend');
|
||||
var cssSelect = require('css-select');
|
||||
|
||||
var svgoCssSelectAdapter = require('./css-select-adapter');
|
||||
var cssSelectOpts = {
|
||||
xmlMode: true,
|
||||
adapter: svgoCssSelectAdapter
|
||||
};
|
||||
|
||||
var JSAPI = module.exports = function(data, parentNode) {
|
||||
EXTEND(this, data);
|
||||
Object.assign(this, data);
|
||||
if (parentNode) {
|
||||
Object.defineProperty(this, 'parentNode', {
|
||||
writable: true,
|
||||
@@ -22,13 +28,12 @@ JSAPI.prototype.clone = function() {
|
||||
var nodeData = {};
|
||||
|
||||
Object.keys(node).forEach(function(key) {
|
||||
if (key !== 'content') {
|
||||
if (key !== 'class' && key !== 'style' && key !== 'content') {
|
||||
nodeData[key] = node[key];
|
||||
}
|
||||
});
|
||||
|
||||
// Deep-clone node data
|
||||
// This is still faster than using EXTEND(true…)
|
||||
// Deep-clone node data.
|
||||
nodeData = JSON.parse(JSON.stringify(nodeData));
|
||||
|
||||
// parentNode gets set to a proper object by the parent clone,
|
||||
@@ -36,6 +41,12 @@ JSAPI.prototype.clone = function() {
|
||||
// in the constructor.
|
||||
var clonedNode = new JSAPI(nodeData, !!node.parentNode);
|
||||
|
||||
if (node.class) {
|
||||
clonedNode.class = node.class.clone(clonedNode);
|
||||
}
|
||||
if (node.style) {
|
||||
clonedNode.style = node.style.clone(clonedNode);
|
||||
}
|
||||
if (node.content) {
|
||||
clonedNode.content = node.content.map(function(childNode) {
|
||||
var clonedChild = childNode.clone();
|
||||
@@ -90,6 +101,20 @@ JSAPI.prototype.renameElem = function(name) {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Find the closest ancestor of the current element.
|
||||
* @param elemName
|
||||
*
|
||||
* @return {?Object}
|
||||
*/
|
||||
JSAPI.prototype.closestElem = function(elemName) {
|
||||
var elem = this;
|
||||
|
||||
while ((elem = elem.parentNode) && !elem.isElem(elemName));
|
||||
|
||||
return elem;
|
||||
};
|
||||
|
||||
/**
|
||||
* Changes content by removing elements and/or adding new elements.
|
||||
*
|
||||
@@ -224,7 +249,10 @@ JSAPI.prototype.renameElem = function(name) {
|
||||
|
||||
if (!arguments.length) return false;
|
||||
|
||||
if (Array.isArray(name)) name.forEach(this.removeAttr, this);
|
||||
if (Array.isArray(name)) {
|
||||
name.forEach(this.removeAttr, this);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.hasAttr(name)) return false;
|
||||
|
||||
@@ -255,6 +283,14 @@ JSAPI.prototype.renameElem = function(name) {
|
||||
this.attrs = this.attrs || {};
|
||||
this.attrs[attr.name] = attr;
|
||||
|
||||
if(attr.name === 'class') { // newly added class attribute
|
||||
this.class.hasClass();
|
||||
}
|
||||
|
||||
if(attr.name === 'style') { // newly added style attribute
|
||||
this.style.hasStyle();
|
||||
}
|
||||
|
||||
return this.attrs[attr.name];
|
||||
|
||||
};
|
||||
@@ -296,3 +332,41 @@ JSAPI.prototype.renameElem = function(name) {
|
||||
return false;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluate a string of CSS selectors against the element and returns matched elements.
|
||||
*
|
||||
* @param {String} selectors CSS selector(s) string
|
||||
* @return {Array} null if no elements matched
|
||||
*/
|
||||
JSAPI.prototype.querySelectorAll = function(selectors) {
|
||||
|
||||
var matchedEls = cssSelect(selectors, this, cssSelectOpts);
|
||||
|
||||
return matchedEls.length > 0 ? matchedEls : null;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Evaluate a string of CSS selectors against the element and returns only the first matched element.
|
||||
*
|
||||
* @param {String} selectors CSS selector(s) string
|
||||
* @return {Array} null if no element matched
|
||||
*/
|
||||
JSAPI.prototype.querySelector = function(selectors) {
|
||||
|
||||
return cssSelect.selectOne(selectors, this, cssSelectOpts);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Test if a selector matches a given element.
|
||||
*
|
||||
* @param {String} selector CSS selector string
|
||||
* @return {Boolean} true if element would be selected by selector string, false if it does not
|
||||
*/
|
||||
JSAPI.prototype.matches = function(selector) {
|
||||
|
||||
return cssSelect.is(this, selector, cssSelectOpts);
|
||||
|
||||
};
|
||||
|
||||
19
node_modules/svgo/lib/svgo/plugins.js
generated
vendored
19
node_modules/svgo/lib/svgo/plugins.js
generated
vendored
@@ -6,22 +6,23 @@
|
||||
* @module plugins
|
||||
*
|
||||
* @param {Object} data input data
|
||||
* @param {Object} info extra information
|
||||
* @param {Object} plugins plugins object from config
|
||||
* @return {Object} output data
|
||||
*/
|
||||
module.exports = function(data, plugins) {
|
||||
module.exports = function(data, info, plugins) {
|
||||
|
||||
plugins.forEach(function(group) {
|
||||
|
||||
switch(group[0].type) {
|
||||
case 'perItem':
|
||||
data = perItem(data, group);
|
||||
data = perItem(data, info, group);
|
||||
break;
|
||||
case 'perItemReverse':
|
||||
data = perItem(data, group, true);
|
||||
data = perItem(data, info, group, true);
|
||||
break;
|
||||
case 'full':
|
||||
data = full(data, group);
|
||||
data = full(data, info, group);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -35,11 +36,12 @@ module.exports = function(data, plugins) {
|
||||
* Direct or reverse per-item loop.
|
||||
*
|
||||
* @param {Object} data input data
|
||||
* @param {Object} info extra information
|
||||
* @param {Array} plugins plugins list to process
|
||||
* @param {Boolean} [reverse] reverse pass?
|
||||
* @return {Object} output data
|
||||
*/
|
||||
function perItem(data, plugins, reverse) {
|
||||
function perItem(data, info, plugins, reverse) {
|
||||
|
||||
function monkeys(items) {
|
||||
|
||||
@@ -56,7 +58,7 @@ function perItem(data, plugins, reverse) {
|
||||
for (var i = 0; filter && i < plugins.length; i++) {
|
||||
var plugin = plugins[i];
|
||||
|
||||
if (plugin.active && plugin.fn(item, plugin.params) === false) {
|
||||
if (plugin.active && plugin.fn(item, plugin.params, info) === false) {
|
||||
filter = false;
|
||||
}
|
||||
}
|
||||
@@ -82,14 +84,15 @@ function perItem(data, plugins, reverse) {
|
||||
* "Full" plugins.
|
||||
*
|
||||
* @param {Object} data input data
|
||||
* @param {Object} info extra information
|
||||
* @param {Array} plugins plugins list to process
|
||||
* @return {Object} output data
|
||||
*/
|
||||
function full(data, plugins) {
|
||||
function full(data, info, plugins) {
|
||||
|
||||
plugins.forEach(function(plugin) {
|
||||
if (plugin.active) {
|
||||
data = plugin.fn(data, plugin.params);
|
||||
data = plugin.fn(data, plugin.params, info);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
21
node_modules/svgo/lib/svgo/svg2js.js
generated
vendored
21
node_modules/svgo/lib/svgo/svg2js.js
generated
vendored
@@ -2,6 +2,8 @@
|
||||
|
||||
var SAX = require('sax'),
|
||||
JSAPI = require('./jsAPI.js'),
|
||||
CSSClassList = require('./css-class-list'),
|
||||
CSSStyleDeclaration = require('./css-style-declaration'),
|
||||
entityDeclaration = /<!ENTITY\s+(\S+)\s+(?:'([^\']+)'|"([^\"]+)")\s*>/g;
|
||||
|
||||
var config = {
|
||||
@@ -22,7 +24,7 @@ var config = {
|
||||
module.exports = function(data, callback) {
|
||||
|
||||
var sax = SAX.parser(config.strict, config),
|
||||
root = new JSAPI({ elem: '#document' }),
|
||||
root = new JSAPI({ elem: '#document', content: [] }),
|
||||
current = root,
|
||||
stack = [root],
|
||||
textContext = null,
|
||||
@@ -85,13 +87,24 @@ module.exports = function(data, callback) {
|
||||
var elem = {
|
||||
elem: data.name,
|
||||
prefix: data.prefix,
|
||||
local: data.local
|
||||
local: data.local,
|
||||
attrs: {}
|
||||
};
|
||||
|
||||
if (Object.keys(data.attributes).length) {
|
||||
elem.attrs = {};
|
||||
elem.class = new CSSClassList(elem);
|
||||
elem.style = new CSSStyleDeclaration(elem);
|
||||
|
||||
if (Object.keys(data.attributes).length) {
|
||||
for (var name in data.attributes) {
|
||||
|
||||
if (name === 'class') { // has class attribute
|
||||
elem.class.hasClass();
|
||||
}
|
||||
|
||||
if (name === 'style') { // has style attribute
|
||||
elem.style.hasStyle();
|
||||
}
|
||||
|
||||
elem.attrs[name] = {
|
||||
name: name,
|
||||
value: data.attributes[name].value,
|
||||
|
||||
24
node_modules/svgo/lib/svgo/tools.js
generated
vendored
24
node_modules/svgo/lib/svgo/tools.js
generated
vendored
@@ -1,5 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
var FS = require('fs');
|
||||
|
||||
/**
|
||||
* Encode plain SVG data string into Data URI string.
|
||||
*
|
||||
@@ -15,9 +17,12 @@ exports.encodeSVGDatauri = function(str, type) {
|
||||
if (!type || type === 'base64') {
|
||||
|
||||
prefix += ';base64,';
|
||||
|
||||
str = prefix + new Buffer(str).toString('base64');
|
||||
|
||||
if (Buffer.from) {
|
||||
str = prefix + Buffer.from(str).toString('base64');
|
||||
} else {
|
||||
str = prefix + new Buffer(str).toString('base64');
|
||||
}
|
||||
|
||||
// URI encoded
|
||||
} else if (type === 'enc') {
|
||||
|
||||
@@ -145,3 +150,16 @@ var removeLeadingZero = exports.removeLeadingZero = function(num) {
|
||||
return strNum;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
};
|
||||
|
||||
53
node_modules/svgo/package.json
generated
vendored
53
node_modules/svgo/package.json
generated
vendored
@@ -1,26 +1,26 @@
|
||||
{
|
||||
"_from": "svgo@^0.7.0",
|
||||
"_id": "svgo@0.7.2",
|
||||
"_from": "svgo@^1.0.0",
|
||||
"_id": "svgo@1.2.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
|
||||
"_integrity": "sha512-xBfxJxfk4UeVN8asec9jNxHiv3UAMv/ujwBWGYvQhhMb2u3YTGKkiybPcLFDLq7GLLWE9wa73e0/m8L5nTzQbw==",
|
||||
"_location": "/svgo",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "svgo@^0.7.0",
|
||||
"raw": "svgo@^1.0.0",
|
||||
"name": "svgo",
|
||||
"escapedName": "svgo",
|
||||
"rawSpec": "^0.7.0",
|
||||
"rawSpec": "^1.0.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^0.7.0"
|
||||
"fetchSpec": "^1.0.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/postcss-svgo"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
|
||||
"_shasum": "9f5772413952135c6fefbf40afe6a4faa88b4bb5",
|
||||
"_spec": "svgo@^0.7.0",
|
||||
"_resolved": "https://registry.npmjs.org/svgo/-/svgo-1.2.0.tgz",
|
||||
"_shasum": "305a8fc0f4f9710828c65039bb93d5793225ffc3",
|
||||
"_spec": "svgo@^1.0.0",
|
||||
"_where": "C:\\xampp\\htdocs\\w4rpservices\\node_modules\\postcss-svgo",
|
||||
"author": {
|
||||
"name": "Kir Belevich",
|
||||
@@ -48,22 +48,32 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"coa": "~1.0.1",
|
||||
"colors": "~1.1.2",
|
||||
"csso": "~2.3.1",
|
||||
"js-yaml": "~3.7.0",
|
||||
"chalk": "^2.4.1",
|
||||
"coa": "^2.0.2",
|
||||
"css-select": "^2.0.0",
|
||||
"css-select-base-adapter": "^0.1.1",
|
||||
"css-tree": "1.0.0-alpha.28",
|
||||
"css-url-regex": "^1.1.0",
|
||||
"csso": "^3.5.1",
|
||||
"js-yaml": "^3.12.0",
|
||||
"mkdirp": "~0.5.1",
|
||||
"sax": "~1.2.1",
|
||||
"whet.extend": "~0.9.9"
|
||||
"object.values": "^1.1.0",
|
||||
"sax": "~1.2.4",
|
||||
"stable": "^0.1.8",
|
||||
"unquote": "~1.1.1",
|
||||
"util.promisify": "~1.0.0"
|
||||
},
|
||||
"deprecated": false,
|
||||
"description": "Nodejs-based tool for optimizing SVG vector graphics files",
|
||||
"devDependencies": {
|
||||
"coveralls": "~2.11.14",
|
||||
"coveralls": "^3.0.3",
|
||||
"fs-extra": "~4.0.3",
|
||||
"istanbul": "~0.4.5",
|
||||
"mocha": "~3.2.0",
|
||||
"jshint": "~2.9.5",
|
||||
"mocha": "~4.0.1",
|
||||
"mocha-istanbul": "~0.3.0",
|
||||
"should": "11.2.0"
|
||||
"mock-stdin": "~0.3.1",
|
||||
"should": "~13.1.2"
|
||||
},
|
||||
"directories": {
|
||||
"bin": "./bin",
|
||||
@@ -71,7 +81,7 @@
|
||||
"example": "./examples"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
"node": ">=4.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/svg/svgo",
|
||||
"keywords": [
|
||||
@@ -88,8 +98,9 @@
|
||||
"url": "git://github.com/svg/svgo.git"
|
||||
},
|
||||
"scripts": {
|
||||
"jshint": "jshint --show-non-errors .",
|
||||
"jshint": "npm run lint",
|
||||
"lint": "jshint --show-non-errors .",
|
||||
"test": "set NODE_ENV=test && mocha"
|
||||
},
|
||||
"version": "0.7.2"
|
||||
"version": "1.2.0"
|
||||
}
|
||||
|
||||
77
node_modules/svgo/plugins/_collections.js
generated
vendored
77
node_modules/svgo/plugins/_collections.js
generated
vendored
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
// http://www.w3.org/TR/SVG/intro.html#Definitions
|
||||
// http://www.w3.org/TR/SVG11/intro.html#Definitions
|
||||
exports.elemsGroups = {
|
||||
animation: ['animate', 'animateColor', 'animateMotion', 'animateTransform', 'set'],
|
||||
descriptive: ['desc', 'metadata', 'title'],
|
||||
@@ -17,7 +17,7 @@ exports.elemsGroups = {
|
||||
|
||||
exports.pathElems = ['path', 'glyph', 'missing-glyph'];
|
||||
|
||||
// http://www.w3.org/TR/SVG/intro.html#Definitions
|
||||
// http://www.w3.org/TR/SVG11/intro.html#Definitions
|
||||
exports.attrsGroups = {
|
||||
animationAddition: ['additive', 'accumulate'],
|
||||
animationAttributeTarget: ['attributeType', 'attributeName'],
|
||||
@@ -30,7 +30,6 @@ exports.attrsGroups = {
|
||||
presentation: [
|
||||
'alignment-baseline',
|
||||
'baseline-shift',
|
||||
'buffered-rendering',
|
||||
'clip',
|
||||
'clip-path',
|
||||
'clip-rule',
|
||||
@@ -60,7 +59,6 @@ exports.attrsGroups = {
|
||||
'glyph-orientation-horizontal',
|
||||
'glyph-orientation-vertical',
|
||||
'image-rendering',
|
||||
'kerning',
|
||||
'letter-spacing',
|
||||
'lighting-color',
|
||||
'marker-end',
|
||||
@@ -69,10 +67,9 @@ exports.attrsGroups = {
|
||||
'mask',
|
||||
'opacity',
|
||||
'overflow',
|
||||
'paint-order',
|
||||
'pointer-events',
|
||||
'shape-rendering',
|
||||
'solid-color',
|
||||
'solid-opacity',
|
||||
'stop-color',
|
||||
'stop-opacity',
|
||||
'stroke',
|
||||
@@ -83,18 +80,14 @@ exports.attrsGroups = {
|
||||
'stroke-miterlimit',
|
||||
'stroke-opacity',
|
||||
'stroke-width',
|
||||
'paint-order',
|
||||
'text-anchor',
|
||||
'text-decoration',
|
||||
'text-overflow',
|
||||
'white-space',
|
||||
'text-rendering',
|
||||
'transform',
|
||||
'unicode-bidi',
|
||||
'vector-effect',
|
||||
'viewport-fill',
|
||||
'viewport-fill-opacity',
|
||||
'visibility',
|
||||
'white-space',
|
||||
'word-spacing',
|
||||
'writing-mode'
|
||||
],
|
||||
@@ -113,8 +106,6 @@ exports.attrsGroupsDefaults = {
|
||||
'clip-rule': 'nonzero',
|
||||
mask: 'none',
|
||||
opacity: '1',
|
||||
'solid-color': '#000',
|
||||
'solid-opacity': '1',
|
||||
'stop-color': '#000',
|
||||
'stop-opacity': '1',
|
||||
'fill-opacity': '1',
|
||||
@@ -130,8 +121,6 @@ exports.attrsGroupsDefaults = {
|
||||
'stroke-opacity': '1',
|
||||
'paint-order': 'normal',
|
||||
'vector-effect': 'none',
|
||||
'viewport-fill': 'none',
|
||||
'viewport-fill-opacity': '1',
|
||||
display: 'inline',
|
||||
visibility: 'visible',
|
||||
'marker-start': 'none',
|
||||
@@ -143,7 +132,6 @@ exports.attrsGroupsDefaults = {
|
||||
'shape-rendering': 'auto',
|
||||
'text-rendering': 'auto',
|
||||
'image-rendering': 'auto',
|
||||
'buffered-rendering': 'auto',
|
||||
'font-style': 'normal',
|
||||
'font-variant': 'normal',
|
||||
'font-weight': 'normal',
|
||||
@@ -168,7 +156,7 @@ exports.attrsGroupsDefaults = {
|
||||
transferFunction: {slope: '1', intercept: '0', amplitude: '1', exponent: '1', offset: '0'}
|
||||
};
|
||||
|
||||
// http://www.w3.org/TR/SVG/eltindex.html
|
||||
// http://www.w3.org/TR/SVG11/eltindex.html
|
||||
exports.elems = {
|
||||
a: {
|
||||
attrsGroups: [
|
||||
@@ -788,6 +776,7 @@ exports.elems = {
|
||||
'style',
|
||||
'externalResourcesRequired',
|
||||
'preserveAspectRatio',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
defaults: {
|
||||
@@ -1002,6 +991,7 @@ exports.elems = {
|
||||
'filterRes',
|
||||
'filterUnits',
|
||||
'primitiveUnits',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
defaults: {
|
||||
@@ -1140,6 +1130,7 @@ exports.elems = {
|
||||
'xlink'
|
||||
],
|
||||
attrs: [
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
content: [
|
||||
@@ -1384,6 +1375,7 @@ exports.elems = {
|
||||
'y',
|
||||
'width',
|
||||
'height',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
defaults: {
|
||||
@@ -1441,6 +1433,7 @@ exports.elems = {
|
||||
'gradientUnits',
|
||||
'gradientTransform',
|
||||
'spreadMethod',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
defaults: {
|
||||
@@ -1620,6 +1613,7 @@ exports.elems = {
|
||||
],
|
||||
attrs: [
|
||||
'externalResourcesRequired',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
contentGroups: [
|
||||
@@ -1666,6 +1660,7 @@ exports.elems = {
|
||||
'patternUnits',
|
||||
'patternContentUnits',
|
||||
'patternTransform',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
defaults: {
|
||||
@@ -1762,6 +1757,7 @@ exports.elems = {
|
||||
'gradientUnits',
|
||||
'gradientTransform',
|
||||
'spreadMethod',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
defaults: {
|
||||
@@ -1871,6 +1867,7 @@ exports.elems = {
|
||||
attrs: [
|
||||
'externalResourcesRequired',
|
||||
'type',
|
||||
'href',
|
||||
'xlink:href'
|
||||
]
|
||||
},
|
||||
@@ -2119,6 +2116,7 @@ exports.elems = {
|
||||
'class',
|
||||
'style',
|
||||
'externalResourcesRequired',
|
||||
'href',
|
||||
'xlink:href',
|
||||
'startOffset',
|
||||
'method',
|
||||
@@ -2164,6 +2162,7 @@ exports.elems = {
|
||||
'class',
|
||||
'style',
|
||||
'externalResourcesRequired',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
contentGroups: [
|
||||
@@ -2224,6 +2223,7 @@ exports.elems = {
|
||||
'y',
|
||||
'width',
|
||||
'height',
|
||||
'href',
|
||||
'xlink:href'
|
||||
],
|
||||
defaults: {
|
||||
@@ -2279,10 +2279,18 @@ exports.editorNamespaces = [
|
||||
'http://ns.adobe.com/Flows/1.0/',
|
||||
'http://ns.adobe.com/ImageReplacement/1.0/',
|
||||
'http://ns.adobe.com/GenericCustomNamespace/1.0/',
|
||||
'http://ns.adobe.com/XPath/1.0/'
|
||||
'http://ns.adobe.com/XPath/1.0/',
|
||||
'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'
|
||||
];
|
||||
|
||||
// http://www.w3.org/TR/SVG/linking.html#processingIRI
|
||||
// http://www.w3.org/TR/SVG11/linking.html#processingIRI
|
||||
exports.referencesProps = [
|
||||
'clip-path',
|
||||
'color-profile',
|
||||
@@ -2296,7 +2304,7 @@ exports.referencesProps = [
|
||||
'style'
|
||||
];
|
||||
|
||||
// http://www.w3.org/TR/SVG/propidx.html
|
||||
// http://www.w3.org/TR/SVG11/propidx.html
|
||||
exports.inheritableAttrs = [
|
||||
'clip-rule',
|
||||
'color',
|
||||
@@ -2306,6 +2314,7 @@ exports.inheritableAttrs = [
|
||||
'color-rendering',
|
||||
'cursor',
|
||||
'direction',
|
||||
'dominant-baseline',
|
||||
'fill',
|
||||
'fill-opacity',
|
||||
'fill-rule',
|
||||
@@ -2320,12 +2329,12 @@ exports.inheritableAttrs = [
|
||||
'glyph-orientation-horizontal',
|
||||
'glyph-orientation-vertical',
|
||||
'image-rendering',
|
||||
'kerning',
|
||||
'letter-spacing',
|
||||
'marker',
|
||||
'marker-end',
|
||||
'marker-mid',
|
||||
'marker-start',
|
||||
'paint-order',
|
||||
'pointer-events',
|
||||
'shape-rendering',
|
||||
'stroke',
|
||||
@@ -2340,12 +2349,23 @@ exports.inheritableAttrs = [
|
||||
'text-rendering',
|
||||
'transform',
|
||||
'visibility',
|
||||
'white-space',
|
||||
'word-spacing',
|
||||
'writing-mode'
|
||||
];
|
||||
|
||||
// http://www.w3.org/TR/SVG/single-page.html#types-ColorKeywords
|
||||
exports.presentationNonInheritableGroupAttrs = [
|
||||
'display',
|
||||
'clip-path',
|
||||
'filter',
|
||||
'mask',
|
||||
'opacity',
|
||||
'text-decoration',
|
||||
'transform',
|
||||
'unicode-bidi',
|
||||
'visibility'
|
||||
];
|
||||
|
||||
// http://www.w3.org/TR/SVG11/single-page.html#types-ColorKeywords
|
||||
exports.colorsNames = {
|
||||
'aliceblue': '#f0f8ff',
|
||||
'antiquewhite': '#faebd7',
|
||||
@@ -2373,6 +2393,7 @@ exports.colorsNames = {
|
||||
'darkgoldenrod': '#b8860b',
|
||||
'darkgray': '#a9a9a9',
|
||||
'darkgreen': '#006400',
|
||||
'darkgrey': '#a9a9a9',
|
||||
'darkkhaki': '#bdb76b',
|
||||
'darkmagenta': '#8b008b',
|
||||
'darkolivegreen': '#556b2f',
|
||||
@@ -2383,11 +2404,13 @@ exports.colorsNames = {
|
||||
'darkseagreen': '#8fbc8f',
|
||||
'darkslateblue': '#483d8b',
|
||||
'darkslategray': '#2f4f4f',
|
||||
'darkslategrey': '#2f4f4f',
|
||||
'darkturquoise': '#00ced1',
|
||||
'darkviolet': '#9400d3',
|
||||
'deeppink': '#ff1493',
|
||||
'deepskyblue': '#00bfff',
|
||||
'dimgray': '#696969',
|
||||
'dimgrey': '#696969',
|
||||
'dodgerblue': '#1e90ff',
|
||||
'firebrick': '#b22222',
|
||||
'floralwhite': '#fffaf0',
|
||||
@@ -2400,6 +2423,7 @@ exports.colorsNames = {
|
||||
'gray': '#808080',
|
||||
'green': '#008000',
|
||||
'greenyellow': '#adff2f',
|
||||
'grey': '#808080',
|
||||
'honeydew': '#f0fff0',
|
||||
'hotpink': '#ff69b4',
|
||||
'indianred': '#cd5c5c',
|
||||
@@ -2414,6 +2438,7 @@ exports.colorsNames = {
|
||||
'lightcoral': '#f08080',
|
||||
'lightcyan': '#e0ffff',
|
||||
'lightgoldenrodyellow': '#fafad2',
|
||||
'lightgray': '#d3d3d3',
|
||||
'lightgreen': '#90ee90',
|
||||
'lightgrey': '#d3d3d3',
|
||||
'lightpink': '#ffb6c1',
|
||||
@@ -2421,6 +2446,7 @@ exports.colorsNames = {
|
||||
'lightseagreen': '#20b2aa',
|
||||
'lightskyblue': '#87cefa',
|
||||
'lightslategray': '#789',
|
||||
'lightslategrey': '#789',
|
||||
'lightsteelblue': '#b0c4de',
|
||||
'lightyellow': '#ffffe0',
|
||||
'lime': '#0f0',
|
||||
@@ -2460,6 +2486,7 @@ exports.colorsNames = {
|
||||
'plum': '#dda0dd',
|
||||
'powderblue': '#b0e0e6',
|
||||
'purple': '#800080',
|
||||
'rebeccapurple': '#639',
|
||||
'red': '#f00',
|
||||
'rosybrown': '#bc8f8f',
|
||||
'royalblue': '#4169e1',
|
||||
@@ -2473,6 +2500,7 @@ exports.colorsNames = {
|
||||
'skyblue': '#87ceeb',
|
||||
'slateblue': '#6a5acd',
|
||||
'slategray': '#708090',
|
||||
'slategrey': '#708090',
|
||||
'snow': '#fffafa',
|
||||
'springgreen': '#00ff7f',
|
||||
'steelblue': '#4682b4',
|
||||
@@ -2512,6 +2540,7 @@ exports.colorsShortNames = {
|
||||
'#dda0dd': 'plum',
|
||||
'#800080': 'purple',
|
||||
'#f00': 'red',
|
||||
'#ff0000': 'red',
|
||||
'#fa8072': 'salmon',
|
||||
'#a0522d': 'sienna',
|
||||
'#c0c0c0': 'silver',
|
||||
@@ -2523,7 +2552,7 @@ exports.colorsShortNames = {
|
||||
'#f5deb3': 'wheat'
|
||||
};
|
||||
|
||||
// http://www.w3.org/TR/SVG/single-page.html#types-DataTypeColor
|
||||
// http://www.w3.org/TR/SVG11/single-page.html#types-DataTypeColor
|
||||
exports.colorsProps = [
|
||||
'color', 'fill', 'stroke', 'stop-color', 'flood-color', 'lighting-color'
|
||||
];
|
||||
|
||||
58
node_modules/svgo/plugins/_path.js
generated
vendored
58
node_modules/svgo/plugins/_path.js
generated
vendored
@@ -1,8 +1,16 @@
|
||||
/* global a2c */
|
||||
'use strict';
|
||||
|
||||
var rNumber = String.raw`[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?\s*`,
|
||||
rCommaWsp = String.raw`(?:\s,?\s*|,\s*)`,
|
||||
rNumberCommaWsp = `(${rNumber})` + rCommaWsp,
|
||||
rFlagCommaWsp = `([01])${rCommaWsp}?`,
|
||||
rCoordinatePair = String.raw`(${rNumber})${rCommaWsp}?(${rNumber})`,
|
||||
rArcSeq = (rNumberCommaWsp + '?').repeat(2) + rNumberCommaWsp + rFlagCommaWsp.repeat(2) + rCoordinatePair;
|
||||
|
||||
var regPathInstructions = /([MmLlHhVvCcSsQqTtAaZz])\s*/,
|
||||
regPathData = /[-+]?(?:\d*\.\d+|\d+\.?)([eE][-+]?\d+)?/g,
|
||||
regCoordinateSequence = new RegExp(rNumber, 'g'),
|
||||
regArcArgumentSequence = new RegExp(rArcSeq, 'g'),
|
||||
regNumericValues = /[-+]?(\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/,
|
||||
transform2js = require('./_transforms').transform2js,
|
||||
transformsMultiply = require('./_transforms').transformsMultiply,
|
||||
@@ -53,11 +61,21 @@ exports.path2js = function(path) {
|
||||
}
|
||||
// data item
|
||||
} else {
|
||||
data = data.match(regPathData);
|
||||
/* jshint boss: true */
|
||||
if (instruction == 'A' || instruction == 'a') {
|
||||
var newData = [];
|
||||
for (var args; (args = regArcArgumentSequence.exec(data));) {
|
||||
for (var i = 1; i < args.length; i++) {
|
||||
newData.push(args[i]);
|
||||
}
|
||||
}
|
||||
data = newData;
|
||||
} else {
|
||||
data = data.match(regCoordinateSequence);
|
||||
}
|
||||
if (!data) return;
|
||||
|
||||
data = data.map(Number);
|
||||
|
||||
// Subsequent moveto pairs of coordinates are threated as implicit lineto commands
|
||||
// http://www.w3.org/TR/SVG/paths.html#PathDataMovetoCommands
|
||||
if (instruction == 'M' || instruction == 'm') {
|
||||
@@ -97,7 +115,7 @@ var relative2absolute = exports.relative2absolute = function(data) {
|
||||
subpathPoint = [0, 0],
|
||||
i;
|
||||
|
||||
data = data.map(function(item) {
|
||||
return data.map(function(item) {
|
||||
|
||||
var instruction = item.instruction,
|
||||
itemData = item.data && item.data.slice();
|
||||
@@ -160,8 +178,6 @@ var relative2absolute = exports.relative2absolute = function(data) {
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
return data;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -210,16 +226,22 @@ exports.applyTransforms = function(elem, path, params) {
|
||||
if (scale !== 1) {
|
||||
var strokeWidth = elem.computedAttr('stroke-width') || defaultStrokeWidth;
|
||||
|
||||
if (elem.hasAttr('stroke-width')) {
|
||||
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value.trim()
|
||||
.replace(regNumericValues, function(num) { return removeLeadingZero(num * scale) });
|
||||
} else {
|
||||
elem.addAttr({
|
||||
name: 'stroke-width',
|
||||
prefix: '',
|
||||
local: 'stroke-width',
|
||||
value: strokeWidth.replace(regNumericValues, function(num) { return removeLeadingZero(num * scale) })
|
||||
});
|
||||
if (!elem.hasAttr('vector-effect') || elem.attr('vector-effect').value !== 'non-scaling-stroke') {
|
||||
if (elem.hasAttr('stroke-width')) {
|
||||
elem.attrs['stroke-width'].value = elem.attrs['stroke-width'].value.trim()
|
||||
.replace(regNumericValues, function(num) {
|
||||
return removeLeadingZero(num * scale);
|
||||
});
|
||||
} else {
|
||||
elem.addAttr({
|
||||
name: 'stroke-width',
|
||||
prefix: '',
|
||||
local: 'stroke-width',
|
||||
value: strokeWidth.replace(regNumericValues, function(num) {
|
||||
return removeLeadingZero(num * scale);
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (id) { // Stroke and stroke-width can be redefined with <use>
|
||||
@@ -754,7 +776,7 @@ function gatherPoints(points, item, index, path) {
|
||||
prevCtrlPoint = [data[2] - data[0], data[3] - data[1]]; // Save control point for shorthand
|
||||
break;
|
||||
case 'T':
|
||||
if (prev.instruction == 'Q' && prev.instruction == 'T') {
|
||||
if (prev.instruction == 'Q' || prev.instruction == 'T') {
|
||||
ctrlPoint = [basePoint[0] + prevCtrlPoint[0], basePoint[1] + prevCtrlPoint[1]];
|
||||
addPoint(subPath, ctrlPoint);
|
||||
prevCtrlPoint = [data[0] - ctrlPoint[0], data[1] - ctrlPoint[1]];
|
||||
@@ -768,7 +790,7 @@ function gatherPoints(points, item, index, path) {
|
||||
prevCtrlPoint = [data[4] - data[2], data[5] - data[3]]; // Save control point for shorthand
|
||||
break;
|
||||
case 'S':
|
||||
if (prev.instruction == 'C' && prev.instruction == 'S') {
|
||||
if (prev.instruction == 'C' || prev.instruction == 'S') {
|
||||
addPoint(subPath, [basePoint[0] + .5 * prevCtrlPoint[0], basePoint[1] + .5 * prevCtrlPoint[1]]);
|
||||
ctrlPoint = [basePoint[0] + prevCtrlPoint[0], basePoint[1] + prevCtrlPoint[1]];
|
||||
}
|
||||
|
||||
33
node_modules/svgo/plugins/_transforms.js
generated
vendored
33
node_modules/svgo/plugins/_transforms.js
generated
vendored
@@ -42,8 +42,8 @@ exports.transform2js = function(transformString) {
|
||||
}
|
||||
});
|
||||
|
||||
return transforms;
|
||||
|
||||
// return empty array if broken transform (no data)
|
||||
return current && current.data ? transforms : [];
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -65,9 +65,7 @@ exports.transformsMultiply = function(transforms) {
|
||||
// multiply all matrices into one
|
||||
transforms = {
|
||||
name: 'matrix',
|
||||
data: transforms.reduce(function(a, b) {
|
||||
return multiplyTransformMatrices(a, b);
|
||||
})
|
||||
data: transforms.length > 0 ? transforms.reduce(multiplyTransformMatrices) : []
|
||||
};
|
||||
|
||||
return transforms;
|
||||
@@ -117,7 +115,7 @@ var mth = exports.mth = {
|
||||
|
||||
/**
|
||||
* Decompose matrix into simple transforms. See
|
||||
* http://www.maths-informatique-jeux.com/blog/frederic/?post/2013/12/01/Decomposition-of-2D-transform-matrices
|
||||
* http://frederic-wang.fr/decomposition-of-2d-transform-matrices.html
|
||||
*
|
||||
* @param {Object} data matrix transform object
|
||||
* @return {Object|Array} transforms array or original transform object
|
||||
@@ -126,11 +124,11 @@ exports.matrixToTransform = function(transform, params) {
|
||||
var floatPrecision = params.floatPrecision,
|
||||
data = transform.data,
|
||||
transforms = [],
|
||||
sx = +Math.sqrt(data[0] * data[0] + data[1] * data[1]).toFixed(params.transformPrecision),
|
||||
sx = +Math.hypot(data[0], data[1]).toFixed(params.transformPrecision),
|
||||
sy = +((data[0] * data[3] - data[1] * data[2]) / sx).toFixed(params.transformPrecision),
|
||||
colsSum = data[0] * data[2] + data[1] * data[3],
|
||||
rowsSum = data[0] * data[1] + data[2] * data[3],
|
||||
scaleBefore = rowsSum || +(sx == sy);
|
||||
scaleBefore = rowsSum != 0 || sx == sy;
|
||||
|
||||
// [..., ..., ..., ..., tx, ty] → translate(tx, ty)
|
||||
if (data[4] || data[5]) {
|
||||
@@ -151,11 +149,11 @@ exports.matrixToTransform = function(transform, params) {
|
||||
// [sx·cos(a), sy·sin(a), sx·-sin(a), sy·cos(a), x, y] → scale(sx, sy)·rotate(a[, cx, cy]) (if !scaleBefore)
|
||||
} else if (!colsSum || (sx == 1 && sy == 1) || !scaleBefore) {
|
||||
if (!scaleBefore) {
|
||||
sx = (data[0] < 0 ? -1 : 1) * Math.sqrt(data[0] * data[0] + data[2] * data[2]);
|
||||
sy = (data[3] < 0 ? -1 : 1) * Math.sqrt(data[1] * data[1] + data[3] * data[3]);
|
||||
sx = (data[0] < 0 ? -1 : 1) * Math.hypot(data[0], data[2]);
|
||||
sy = (data[3] < 0 ? -1 : 1) * Math.hypot(data[1], data[3]);
|
||||
transforms.push({ name: 'scale', data: [sx, sy] });
|
||||
}
|
||||
var rotate = [mth.acos(data[0] / sx, floatPrecision) * (data[1] * sy < 0 ? -1 : 1)];
|
||||
var rotate = [mth.acos(data[0] / sx, floatPrecision) * ((scaleBefore ? 1 : sy) * data[1] < 0 ? -1 : 1)];
|
||||
|
||||
if (rotate[0]) transforms.push({ name: 'rotate', data: rotate });
|
||||
|
||||
@@ -262,10 +260,7 @@ exports.transformArc = function(arc, transform) {
|
||||
// Decompose the new ellipse matrix
|
||||
lastCol = m[2] * m[2] + m[3] * m[3],
|
||||
squareSum = m[0] * m[0] + m[1] * m[1] + lastCol,
|
||||
root = Math.sqrt(
|
||||
(Math.pow(m[0] - m[3], 2) + Math.pow(m[1] + m[2], 2)) *
|
||||
(Math.pow(m[0] + m[3], 2) + Math.pow(m[1] - m[2], 2))
|
||||
);
|
||||
root = Math.hypot(m[0] - m[3], m[1] + m[2]) * Math.hypot(m[0] + m[3], m[1] - m[2]);
|
||||
|
||||
if (!root) { // circle
|
||||
arc[0] = arc[1] = Math.sqrt(squareSum / 2);
|
||||
@@ -281,8 +276,14 @@ exports.transformArc = function(arc, transform) {
|
||||
arc[0] = Math.sqrt(majorAxisSqr);
|
||||
arc[1] = Math.sqrt(minorAxisSqr);
|
||||
arc[2] = ((major ? term2 < 0 : term1 > 0) ? -1 : 1) *
|
||||
Math.acos((major ? term1 : term2) / Math.sqrt(term1 * term1 + term2 * term2)) * 180 / Math.PI;
|
||||
Math.acos((major ? term1 : term2) / Math.hypot(term1, term2)) * 180 / Math.PI;
|
||||
}
|
||||
|
||||
if ((transform[0] < 0) !== (transform[3] < 0)) {
|
||||
// Flip the sweep flag if coordinates are being flipped horizontally XOR vertically
|
||||
arc[4] = 1 - arc[4];
|
||||
}
|
||||
|
||||
return arc;
|
||||
|
||||
};
|
||||
|
||||
59
node_modules/svgo/plugins/addAttributesToSVGElement.js
generated
vendored
59
node_modules/svgo/plugins/addAttributesToSVGElement.js
generated
vendored
@@ -6,17 +6,23 @@ exports.active = false;
|
||||
|
||||
exports.description = 'adds attributes to an outer <svg> element';
|
||||
|
||||
var ENOCLS = 'Error in plugin "addAttributesToSVGElement": absent parameters.\n\
|
||||
It should have a list of classes in "attributes" or one "attribute".\n\
|
||||
Config example:\n\n\
|
||||
\
|
||||
plugins:\n\
|
||||
- addAttributesToSVGElement:\n\
|
||||
attribute: "mySvg"\n\n\
|
||||
\
|
||||
plugins:\n\
|
||||
- addAttributesToSVGElement:\n\
|
||||
attributes: ["mySvg", "size-big"]\n';
|
||||
var ENOCLS = `Error in plugin "addAttributesToSVGElement": absent parameters.
|
||||
It should have a list of "attributes" or one "attribute".
|
||||
Config example:
|
||||
|
||||
plugins:
|
||||
- addAttributesToSVGElement:
|
||||
attribute: "mySvg"
|
||||
|
||||
plugins:
|
||||
- addAttributesToSVGElement:
|
||||
attributes: ["mySvg", "size-big"]
|
||||
|
||||
plugins:
|
||||
- addAttributesToSVGElement:
|
||||
attributes:
|
||||
- focusable: false
|
||||
- data-image: icon`;
|
||||
|
||||
/**
|
||||
* Add attributes to an outer <svg> element. Example config:
|
||||
@@ -29,10 +35,16 @@ plugins:\n\
|
||||
* - addAttributesToSVGElement:
|
||||
* attributes: ['data-icon', 'data-disabled']
|
||||
*
|
||||
* plugins:
|
||||
* - addAttributesToSVGElement:
|
||||
* attributes:
|
||||
* - focusable: false
|
||||
* - data-image: icon
|
||||
*
|
||||
* @author April Arcus
|
||||
*/
|
||||
exports.fn = function(data, params) {
|
||||
if (!params || !(Array.isArray(params.attributes) && params.attributes.some(String) || params.attribute)) {
|
||||
if (!params || !(Array.isArray(params.attributes) || params.attribute)) {
|
||||
console.error(ENOCLS);
|
||||
return data;
|
||||
}
|
||||
@@ -42,11 +54,24 @@ exports.fn = function(data, params) {
|
||||
|
||||
if (svg.isElem('svg')) {
|
||||
attributes.forEach(function (attribute) {
|
||||
if (!svg.hasAttr(attribute)) {
|
||||
svg.addAttr({
|
||||
name: attribute,
|
||||
prefix: '',
|
||||
local: attribute
|
||||
if (typeof attribute === 'string') {
|
||||
if (!svg.hasAttr(attribute)) {
|
||||
svg.addAttr({
|
||||
name: attribute,
|
||||
prefix: '',
|
||||
local: attribute
|
||||
});
|
||||
}
|
||||
} else if (typeof attribute === 'object') {
|
||||
Object.keys(attribute).forEach(function (key) {
|
||||
if (!svg.hasAttr(key)) {
|
||||
svg.addAttr({
|
||||
name: key,
|
||||
value: attribute[key],
|
||||
prefix: '',
|
||||
local: key
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
40
node_modules/svgo/plugins/addClassesToSVGElement.js
generated
vendored
40
node_modules/svgo/plugins/addClassesToSVGElement.js
generated
vendored
@@ -6,17 +6,18 @@ exports.active = false;
|
||||
|
||||
exports.description = 'adds classnames to an outer <svg> element';
|
||||
|
||||
var ENOCLS = 'Error in plugin "addClassesToSVGElement": absent parameters.\n\
|
||||
It should have a list of classes in "classNames" or one "className".\n\
|
||||
Config example:\n\n\
|
||||
\
|
||||
plugins:\n\
|
||||
- addClassesToSVGElement:\n\
|
||||
className: "mySvg"\n\n\
|
||||
\
|
||||
plugins:\n\
|
||||
- addClassesToSVGElement:\n\
|
||||
classNames: ["mySvg", "size-big"]\n';
|
||||
var ENOCLS = `Error in plugin "addClassesToSVGElement": absent parameters.
|
||||
It should have a list of classes in "classNames" or one "className".
|
||||
Config example:
|
||||
|
||||
plugins:
|
||||
- addClassesToSVGElement:
|
||||
className: "mySvg"
|
||||
|
||||
plugins:
|
||||
- addClassesToSVGElement:
|
||||
classNames: ["mySvg", "size-big"]
|
||||
`;
|
||||
|
||||
/**
|
||||
* Add classnames to an outer <svg> element. Example config:
|
||||
@@ -41,22 +42,7 @@ exports.fn = function(data, params) {
|
||||
svg = data.content[0];
|
||||
|
||||
if (svg.isElem('svg')) {
|
||||
if (svg.hasAttr('class')) {
|
||||
var classes = svg.attr('class').value.split(' ');
|
||||
classNames.forEach(function(className){
|
||||
if (classes.indexOf(className) < 0) {
|
||||
classes.push(className);
|
||||
}
|
||||
});
|
||||
svg.attr('class').value = classes.join(' ');
|
||||
} else {
|
||||
svg.addAttr({
|
||||
name: 'class',
|
||||
value: classNames.join(' '),
|
||||
prefix: '',
|
||||
local: 'class'
|
||||
});
|
||||
}
|
||||
svg.class.add.apply(svg.class, classNames);
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
166
node_modules/svgo/plugins/cleanupIDs.js
generated
vendored
166
node_modules/svgo/plugins/cleanupIDs.js
generated
vendored
@@ -9,13 +9,16 @@ exports.description = 'removes unused IDs and minifies used';
|
||||
exports.params = {
|
||||
remove: true,
|
||||
minify: true,
|
||||
prefix: ''
|
||||
prefix: '',
|
||||
preserve: [],
|
||||
preservePrefixes: [],
|
||||
force: false
|
||||
};
|
||||
|
||||
var referencesProps = require('./_collections').referencesProps,
|
||||
var referencesProps = new Set(require('./_collections').referencesProps),
|
||||
regReferencesUrl = /\burl\(("|')?#(.+?)\1\)/,
|
||||
regReferencesHref = /^#(.+?)$/,
|
||||
regReferencesBegin = /^(\w+?)\./,
|
||||
regReferencesBegin = /(\w+)\./,
|
||||
styleOrScript = ['style', 'script'],
|
||||
generateIDchars = [
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
|
||||
@@ -33,13 +36,15 @@ var referencesProps = require('./_collections').referencesProps,
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(data, params) {
|
||||
|
||||
var currentID,
|
||||
currentIDstring,
|
||||
IDs = Object.create(null),
|
||||
referencesIDs = Object.create(null),
|
||||
idPrefix = 'id-', // prefix IDs so that values like '__proto__' don't break the work
|
||||
hasStyleOrScript = false;
|
||||
IDs = new Map(),
|
||||
referencesIDs = new Map(),
|
||||
hasStyleOrScript = false,
|
||||
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 = '#',
|
||||
idValuePostfix = '.';
|
||||
|
||||
/**
|
||||
* Bananas!
|
||||
@@ -48,71 +53,66 @@ exports.fn = function(data, params) {
|
||||
* @return {Array} output items
|
||||
*/
|
||||
function monkeys(items) {
|
||||
|
||||
for (var i = 0; i < items.content.length && !hasStyleOrScript; i++) {
|
||||
var item = items.content[i];
|
||||
|
||||
var item = items.content[i],
|
||||
match;
|
||||
|
||||
// check if <style> of <script> presents
|
||||
if (item.isElem(styleOrScript)) {
|
||||
hasStyleOrScript = true;
|
||||
continue;
|
||||
// quit if <style> or <script> present ('force' param prevents quitting)
|
||||
if (!params.force) {
|
||||
if (item.isElem(styleOrScript)) {
|
||||
hasStyleOrScript = true;
|
||||
continue;
|
||||
}
|
||||
// Don't remove IDs if the whole SVG consists only of defs.
|
||||
if (item.isElem('defs') && item.parentNode.isElem('svg')) {
|
||||
var hasDefsOnly = true;
|
||||
for (var j = i + 1; j < items.content.length; j++) {
|
||||
if (items.content[j].isElem()) {
|
||||
hasDefsOnly = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hasDefsOnly) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// …and don't remove any ID if yes
|
||||
if (item.isElem()) {
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
var key;
|
||||
var key, match;
|
||||
|
||||
// save IDs
|
||||
if (attr.name === 'id') {
|
||||
key = idPrefix + attr.value;
|
||||
if (key in IDs) {
|
||||
item.removeAttr('id');
|
||||
key = attr.value;
|
||||
if (IDs.has(key)) {
|
||||
item.removeAttr('id'); // remove repeated id
|
||||
} else {
|
||||
IDs[key] = item;
|
||||
IDs.set(key, item);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// save IDs url() references
|
||||
else if (referencesProps.indexOf(attr.name) > -1) {
|
||||
match = attr.value.match(regReferencesUrl);
|
||||
|
||||
if (match) {
|
||||
key = idPrefix + match[2];
|
||||
if (referencesIDs[key]) {
|
||||
referencesIDs[key].push(attr);
|
||||
} else {
|
||||
referencesIDs[key] = [attr];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// save IDs href references
|
||||
else if (
|
||||
// save references
|
||||
if (referencesProps.has(attr.name) && (match = attr.value.match(regReferencesUrl))) {
|
||||
key = match[2]; // url() reference
|
||||
} else if (
|
||||
attr.local === 'href' && (match = attr.value.match(regReferencesHref)) ||
|
||||
attr.name === 'begin' && (match = attr.value.match(regReferencesBegin))
|
||||
) {
|
||||
key = idPrefix + match[1];
|
||||
if (referencesIDs[key]) {
|
||||
referencesIDs[key].push(attr);
|
||||
} else {
|
||||
referencesIDs[key] = [attr];
|
||||
}
|
||||
key = match[1]; // href reference
|
||||
}
|
||||
if (key) {
|
||||
var ref = referencesIDs.get(key) || [];
|
||||
ref.push(attr);
|
||||
referencesIDs.set(key, ref);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
// go deeper
|
||||
if (item.content) {
|
||||
monkeys(item);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
|
||||
}
|
||||
|
||||
data = monkeys(data);
|
||||
@@ -121,43 +121,50 @@ exports.fn = function(data, params) {
|
||||
return data;
|
||||
}
|
||||
|
||||
var idKey;
|
||||
for (var k in referencesIDs) {
|
||||
if (IDs[k]) {
|
||||
idKey = k;
|
||||
k = k.replace(idPrefix, '');
|
||||
for (var ref of referencesIDs) {
|
||||
var key = ref[0];
|
||||
|
||||
if (IDs.has(key)) {
|
||||
// replace referenced IDs with the minified ones
|
||||
if (params.minify) {
|
||||
if (params.minify && !preserveIDs.has(key) && !idMatchesPrefix(preserveIDPrefixes, key)) {
|
||||
currentIDstring = getIDstring(currentID = generateID(currentID), params);
|
||||
IDs[idKey].attr('id').value = currentIDstring;
|
||||
IDs.get(key).attr('id').value = currentIDstring;
|
||||
|
||||
referencesIDs[idKey].forEach(function(attr) {
|
||||
attr.value = attr.value
|
||||
.replace('#' + k, '#' + currentIDstring)
|
||||
.replace(k + '.', currentIDstring + '.');
|
||||
});
|
||||
|
||||
idKey = idPrefix + k;
|
||||
for (var attr of ref[1]) {
|
||||
attr.value = attr.value.includes(idValuePrefix) ?
|
||||
attr.value.replace(idValuePrefix + key, idValuePrefix + currentIDstring) :
|
||||
attr.value.replace(key + idValuePostfix, currentIDstring + idValuePostfix);
|
||||
}
|
||||
}
|
||||
|
||||
// don't remove referenced IDs
|
||||
delete IDs[idKey];
|
||||
IDs.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
// remove non-referenced IDs attributes from elements
|
||||
if (params.remove) {
|
||||
|
||||
for(var ID in IDs) {
|
||||
IDs[ID].removeAttr('id');
|
||||
for(var keyElem of IDs) {
|
||||
if (!preserveIDs.has(keyElem[0]) && !idMatchesPrefix(preserveIDPrefixes, keyElem[0])) {
|
||||
keyElem[1].removeAttr('id');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
@@ -165,7 +172,6 @@ exports.fn = function(data, params) {
|
||||
* @return {Array} generated ID array
|
||||
*/
|
||||
function generateID(currentID) {
|
||||
|
||||
if (!currentID) return [0];
|
||||
|
||||
currentID[currentID.length - 1]++;
|
||||
@@ -179,14 +185,11 @@ function generateID(currentID) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentID[0] > maxIDindex) {
|
||||
currentID[0] = 0;
|
||||
currentID.unshift(0);
|
||||
}
|
||||
|
||||
return currentID;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -196,13 +199,6 @@ function generateID(currentID) {
|
||||
* @return {String} output ID string
|
||||
*/
|
||||
function getIDstring(arr, params) {
|
||||
|
||||
var str = params.prefix;
|
||||
|
||||
arr.forEach(function(i) {
|
||||
str += generateIDchars[i];
|
||||
});
|
||||
|
||||
return str;
|
||||
|
||||
return str + arr.map(i => generateIDchars[i]).join('');
|
||||
}
|
||||
|
||||
10
node_modules/svgo/plugins/cleanupListOfValues.js
generated
vendored
10
node_modules/svgo/plugins/cleanupListOfValues.js
generated
vendored
@@ -96,8 +96,7 @@ exports.fn = function(item, params) {
|
||||
matchNew = elem.match(/new/);
|
||||
|
||||
// if attribute value matches regNumericValues
|
||||
if(match){
|
||||
|
||||
if (match) {
|
||||
// round it to the fixed precision
|
||||
num = +(+match[1]).toFixed(params.floatPrecision),
|
||||
units = match[3] || '';
|
||||
@@ -122,13 +121,12 @@ exports.fn = function(item, params) {
|
||||
}
|
||||
|
||||
roundedListArr.push(num+units);
|
||||
|
||||
}
|
||||
// if attribute value is "new"(only enable-background).
|
||||
else if(matchNew){
|
||||
|
||||
else if (matchNew) {
|
||||
roundedListArr.push('new');
|
||||
|
||||
} else if (elem) {
|
||||
roundedListArr.push(elem);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
24
node_modules/svgo/plugins/cleanupNumericValues.js
generated
vendored
24
node_modules/svgo/plugins/cleanupNumericValues.js
generated
vendored
@@ -37,24 +37,36 @@ exports.fn = function(item, params) {
|
||||
|
||||
if (item.isElem()) {
|
||||
|
||||
var match;
|
||||
var floatPrecision = params.floatPrecision;
|
||||
|
||||
if (item.hasAttr('viewBox')) {
|
||||
var nums = item.attr('viewBox').value.split(/\s,?\s*|,\s*/g);
|
||||
item.attr('viewBox').value = nums.map(function(value) {
|
||||
var num = +value;
|
||||
return isNaN(num) ? value : +num.toFixed(floatPrecision);
|
||||
}).join(' ');
|
||||
}
|
||||
|
||||
item.eachAttr(function(attr) {
|
||||
match = attr.value.match(regNumericValues);
|
||||
// The `version` attribute is a text string and cannot be rounded
|
||||
if (attr.name === 'version') { return }
|
||||
|
||||
var match = attr.value.match(regNumericValues);
|
||||
|
||||
// if attribute value matches regNumericValues
|
||||
if (match) {
|
||||
// round it to the fixed precision
|
||||
var num = +(+match[1]).toFixed(params.floatPrecision),
|
||||
var num = +(+match[1]).toFixed(floatPrecision),
|
||||
units = match[3] || '';
|
||||
|
||||
// convert absolute values to pixels
|
||||
if (params.convertToPx && units && (units in absoluteLengths)) {
|
||||
var pxNum = +(absoluteLengths[units] * match[1]).toFixed(params.floatPrecision);
|
||||
var pxNum = +(absoluteLengths[units] * match[1]).toFixed(floatPrecision);
|
||||
|
||||
if (String(pxNum).length < match[0].length)
|
||||
num = pxNum,
|
||||
if (String(pxNum).length < match[0].length) {
|
||||
num = pxNum;
|
||||
units = 'px';
|
||||
}
|
||||
}
|
||||
|
||||
// and remove leading zero
|
||||
|
||||
10
node_modules/svgo/plugins/collapseGroups.js
generated
vendored
10
node_modules/svgo/plugins/collapseGroups.js
generated
vendored
@@ -43,17 +43,14 @@ exports.fn = function(item) {
|
||||
|
||||
// non-empty elements
|
||||
if (item.isElem() && !item.isElem('switch') && !item.isEmpty()) {
|
||||
|
||||
item.content.forEach(function(g, i) {
|
||||
|
||||
// non-empty groups
|
||||
if (g.isElem('g') && !g.isEmpty()) {
|
||||
|
||||
// move group attibutes to the single content element
|
||||
if (g.hasAttr() && g.content.length === 1) {
|
||||
var inner = g.content[0];
|
||||
|
||||
if (inner.isElem() && !inner.hasAttr('id') &&
|
||||
if (inner.isElem() && !inner.hasAttr('id') && !g.hasAttr('filter') &&
|
||||
!(g.hasAttr('class') && inner.hasAttr('class')) && (
|
||||
!g.hasAttr('clip-path') && !g.hasAttr('mask') ||
|
||||
inner.isElem('g') && !g.hasAttr('transform') && !inner.hasAttr('transform')
|
||||
@@ -66,6 +63,8 @@ exports.fn = function(item) {
|
||||
inner.addAttr(attr);
|
||||
} else if (attr.name == 'transform') {
|
||||
inner.attr(attr.name).value = attr.value + ' ' + inner.attr(attr.name).value;
|
||||
} else if (inner.hasAttr(attr.name, 'inherit')) {
|
||||
inner.attr(attr.name).value = attr.value;
|
||||
} else if (
|
||||
attrsInheritable.indexOf(attr.name) < 0 &&
|
||||
!inner.hasAttr(attr.name, attr.value)
|
||||
@@ -83,9 +82,6 @@ exports.fn = function(item) {
|
||||
item.spliceContent(i, 1, g.content);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
7
node_modules/svgo/plugins/convertColors.js
generated
vendored
7
node_modules/svgo/plugins/convertColors.js
generated
vendored
@@ -95,8 +95,11 @@ exports.fn = function(item, params) {
|
||||
}
|
||||
|
||||
// Convert hex to short name
|
||||
if (params.shortname && val in collections.colorsShortNames) {
|
||||
val = collections.colorsShortNames[val];
|
||||
if (params.shortname) {
|
||||
var lowerVal = val.toLowerCase();
|
||||
if (lowerVal in collections.colorsShortNames) {
|
||||
val = collections.colorsShortNames[lowerVal];
|
||||
}
|
||||
}
|
||||
|
||||
attr.value = val;
|
||||
|
||||
32
node_modules/svgo/plugins/convertPathData.js
generated
vendored
32
node_modules/svgo/plugins/convertPathData.js
generated
vendored
@@ -22,7 +22,8 @@ exports.params = {
|
||||
collapseRepeated: true,
|
||||
utilizeAbsolute: true,
|
||||
leadingZero: true,
|
||||
negativeExtraSpace: true
|
||||
negativeExtraSpace: true,
|
||||
forceAbsolutePath: false
|
||||
};
|
||||
|
||||
var pathElems = require('./_collections.js').pathElems,
|
||||
@@ -35,7 +36,8 @@ var pathElems = require('./_collections.js').pathElems,
|
||||
error,
|
||||
arcThreshold,
|
||||
arcTolerance,
|
||||
hasMarkerMid;
|
||||
hasMarkerMid,
|
||||
hasStrokeLinecap;
|
||||
|
||||
/**
|
||||
* Convert absolute Path to relative,
|
||||
@@ -66,6 +68,10 @@ exports.fn = function(item, params) {
|
||||
}
|
||||
hasMarkerMid = item.hasAttr('marker-mid');
|
||||
|
||||
var stroke = item.computedAttr('stroke'),
|
||||
strokeLinecap = item.computedAttr('stroke');
|
||||
hasStrokeLinecap = stroke && stroke != 'none' && strokeLinecap && strokeLinecap != 'butt';
|
||||
|
||||
var data = path2js(item);
|
||||
|
||||
// TODO: get rid of functions returns
|
||||
@@ -583,7 +589,7 @@ function filters(path, params) {
|
||||
}
|
||||
|
||||
// remove useless non-first path segments
|
||||
if (params.removeUseless) {
|
||||
if (params.removeUseless && !hasStrokeLinecap) {
|
||||
|
||||
// l 0,0 / h 0 / v 0 / q 0,0 0,0 / t 0,0 / c 0,0 0,0 0,0 / s 0,0 0,0
|
||||
if (
|
||||
@@ -671,11 +677,12 @@ function convertToMixed(path, params) {
|
||||
var absoluteDataStr = cleanupOutData(adata, params),
|
||||
relativeDataStr = cleanupOutData(data, params);
|
||||
|
||||
// Convert to absolute coordinates if it's shorter.
|
||||
// Convert to absolute coordinates if it's shorter or forceAbsolutePath is true.
|
||||
// v-20 -> V0
|
||||
// Don't convert if it fits following previous instruction.
|
||||
// l20 30-10-50 instead of l20 30L20 30
|
||||
if (
|
||||
params.forceAbsolutePath || (
|
||||
absoluteDataStr.length < relativeDataStr.length &&
|
||||
!(
|
||||
params.negativeExtraSpace &&
|
||||
@@ -683,7 +690,7 @@ function convertToMixed(path, params) {
|
||||
prev.instruction.charCodeAt(0) > 96 &&
|
||||
absoluteDataStr.length == relativeDataStr.length - 1 &&
|
||||
(data[0] < 0 || /^0\./.test(data[0]) && prev.data[prev.data.length - 1] % 1)
|
||||
)
|
||||
))
|
||||
) {
|
||||
item.instruction = instruction.toUpperCase();
|
||||
item.data = adata;
|
||||
@@ -840,7 +847,7 @@ function makeLonghand(item, data) {
|
||||
*/
|
||||
|
||||
function getDistance(point1, point2) {
|
||||
return Math.sqrt(Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));
|
||||
return Math.hypot(point1[0] - point2[0], point1[1] - point2[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -885,21 +892,22 @@ function findCircle(curve) {
|
||||
radius = center && getDistance([0, 0], center),
|
||||
tolerance = Math.min(arcThreshold * error, arcTolerance * radius / 100);
|
||||
|
||||
if (center && [1/4, 3/4].every(function(point) {
|
||||
if (center && radius < 1e15 &&
|
||||
[1/4, 3/4].every(function(point) {
|
||||
return Math.abs(getDistance(getCubicBezierPoint(curve, point), center) - radius) <= tolerance;
|
||||
}))
|
||||
return { center: center, radius: radius};
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a curve fits the given circe.
|
||||
* Checks if a curve fits the given circle.
|
||||
*
|
||||
* @param {Object} circle
|
||||
* @param {Array} curve
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function isArc(curve, circle) {
|
||||
function isArc(curve, circle) {
|
||||
var tolerance = Math.min(arcThreshold * error, arcTolerance * circle.radius / 100);
|
||||
|
||||
return [0, 1/4, 1/2, 3/4, 1].every(function(point) {
|
||||
@@ -908,14 +916,14 @@ function isArc(curve, circle) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a previos curve fits the given circe.
|
||||
* Checks if a previous curve fits the given circle.
|
||||
*
|
||||
* @param {Object} circle
|
||||
* @param {Array} curve
|
||||
* @return {Boolean}
|
||||
*/
|
||||
|
||||
function isArcPrev(curve, circle) {
|
||||
function isArcPrev(curve, circle) {
|
||||
return isArc(curve, {
|
||||
center: [circle.center[0] + curve[4], circle.center[1] + curve[5]],
|
||||
radius: circle.radius
|
||||
@@ -952,6 +960,6 @@ function findArcAngle(curve, relCircle) {
|
||||
|
||||
function data2Path(params, pathData) {
|
||||
return pathData.reduce(function(pathString, item) {
|
||||
return pathString += item.instruction + (item.data ? cleanupOutData(roundData(item.data.slice()), params) : '');
|
||||
return pathString + item.instruction + (item.data ? cleanupOutData(roundData(item.data.slice()), params) : '');
|
||||
}, '');
|
||||
}
|
||||
|
||||
50
node_modules/svgo/plugins/convertShapeToPath.js
generated
vendored
50
node_modules/svgo/plugins/convertShapeToPath.js
generated
vendored
@@ -6,6 +6,10 @@ exports.active = true;
|
||||
|
||||
exports.description = 'converts basic shapes to more compact path form';
|
||||
|
||||
exports.params = {
|
||||
convertArcs: false
|
||||
};
|
||||
|
||||
var none = { value: 0 },
|
||||
regNumber = /[-+]?(?:\d*\.\d+|\d+\.?)(?:[eE][-+]?\d+)?/g;
|
||||
|
||||
@@ -22,7 +26,8 @@ var none = { value: 0 },
|
||||
*
|
||||
* @author Lev Solntsev
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
exports.fn = function(item, params) {
|
||||
var convertArcs = params && params.convertArcs;
|
||||
|
||||
if (
|
||||
item.isElem('rect') &&
|
||||
@@ -98,6 +103,47 @@ exports.fn = function(item) {
|
||||
|
||||
item.renameElem('path')
|
||||
.removeAttr('points');
|
||||
}
|
||||
} else if (item.isElem('circle') && convertArcs) {
|
||||
|
||||
var cx = +(item.attr('cx') || none).value;
|
||||
var cy = +(item.attr('cy') || none).value;
|
||||
var r = +(item.attr('r') || none).value;
|
||||
if (isNaN(cx - cy + r)) {
|
||||
return;
|
||||
}
|
||||
var cPathData =
|
||||
'M' + cx + ' ' + (cy - r) +
|
||||
'A' + r + ' ' + r + ' 0 1 0 ' + cx + ' ' + (cy + r) +
|
||||
'A' + r + ' ' + r + ' 0 1 0 ' + cx + ' ' + (cy - r) +
|
||||
'Z';
|
||||
item.addAttr({
|
||||
name: 'd',
|
||||
value: cPathData,
|
||||
prefix: '',
|
||||
local: 'd',
|
||||
});
|
||||
item.renameElem('path').removeAttr(['cx', 'cy', 'r']);
|
||||
|
||||
} else if (item.isElem('ellipse') && convertArcs) {
|
||||
|
||||
var ecx = +(item.attr('cx') || none).value;
|
||||
var ecy = +(item.attr('cy') || none).value;
|
||||
var rx = +(item.attr('rx') || none).value;
|
||||
var ry = +(item.attr('ry') || none).value;
|
||||
if (isNaN(ecx - ecy + rx - ry)) {
|
||||
return;
|
||||
}
|
||||
var ePathData =
|
||||
'M' + ecx + ' ' + (ecy - ry) +
|
||||
'A' + rx + ' ' + ry + ' 0 1 0 ' + ecx + ' ' + (ecy + ry) +
|
||||
'A' + rx + ' ' + ry + ' 0 1 0 ' + ecx + ' ' + (ecy - ry) +
|
||||
'Z';
|
||||
item.addAttr({
|
||||
name: 'd',
|
||||
value: ePathData,
|
||||
prefix: '',
|
||||
local: 'd',
|
||||
});
|
||||
item.renameElem('path').removeAttr(['cx', 'cy', 'rx', 'ry']);
|
||||
}
|
||||
};
|
||||
|
||||
22
node_modules/svgo/plugins/convertStyleToAttrs.js
generated
vendored
22
node_modules/svgo/plugins/convertStyleToAttrs.js
generated
vendored
@@ -7,8 +7,11 @@ exports.active = true;
|
||||
|
||||
exports.description = 'converts style to attributes';
|
||||
|
||||
var EXTEND = require('whet.extend'),
|
||||
stylingProps = require('./_collections').attrsGroups.presentation,
|
||||
exports.params = {
|
||||
keepImportant: false
|
||||
};
|
||||
|
||||
var stylingProps = require('./_collections').attrsGroups.presentation,
|
||||
rEscape = '\\\\(?:[0-9a-f]{1,6}\\s?|\\r\\n|.)', // Like \" or \2051. Code points consume one space.
|
||||
rAttr = '\\s*(' + g('[^:;\\\\]', rEscape) + '*?)\\s*', // attribute name like ‘fill’
|
||||
rSingleQuotes = "'(?:[^'\\n\\r\\\\]|" + rEscape + ")*?(?:'|$)", // string in single quotes: 'smth'
|
||||
@@ -20,13 +23,16 @@ var EXTEND = require('whet.extend'),
|
||||
rParenthesis = '\\(' + g('[^\'"()\\\\]+', rEscape, rSingleQuotes, rQuotes) + '*?' + '\\)',
|
||||
|
||||
// The value. It can have strings and parentheses (see above). Fallbacks to anything in case of unexpected input.
|
||||
rValue = '\\s*(' + g('[^\'"();\\\\]+?', rEscape, rSingleQuotes, rQuotes, rParenthesis, '[^;]*?') + '*?' + ')',
|
||||
rValue = '\\s*(' + g('[^!\'"();\\\\]+?', rEscape, rSingleQuotes, rQuotes, rParenthesis, '[^;]*?') + '*?' + ')',
|
||||
|
||||
// End of declaration. Spaces outside of capturing groups help to do natural trimming.
|
||||
rDeclEnd = '\\s*(?:;\\s*|$)',
|
||||
|
||||
// Important rule
|
||||
rImportant = '(\\s*!important(?![-(\w]))?',
|
||||
|
||||
// Final RegExp to parse CSS declarations.
|
||||
regDeclarationBlock = new RegExp(rAttr + ':' + rValue + rDeclEnd, 'ig'),
|
||||
regDeclarationBlock = new RegExp(rAttr + ':' + rValue + rImportant + rDeclEnd, 'ig'),
|
||||
|
||||
// Comments expression. Honors escape sequences and strings.
|
||||
regStripComments = new RegExp(g(rEscape, rSingleQuotes, rQuotes, '/\\*[^]*?\\*/'), 'ig');
|
||||
@@ -49,7 +55,7 @@ var EXTEND = require('whet.extend'),
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item) {
|
||||
exports.fn = function(item, params) {
|
||||
/* jshint boss: true */
|
||||
|
||||
if (item.elem && item.hasAttr('style')) {
|
||||
@@ -66,7 +72,9 @@ exports.fn = function(item) {
|
||||
|
||||
regDeclarationBlock.lastIndex = 0;
|
||||
for (var rule; rule = regDeclarationBlock.exec(styleValue);) {
|
||||
styles.push([rule[1], rule[2]]);
|
||||
if (!params.keepImportant || !rule[3]) {
|
||||
styles.push([rule[1], rule[2]]);
|
||||
}
|
||||
}
|
||||
|
||||
if (styles.length) {
|
||||
@@ -96,7 +104,7 @@ exports.fn = function(item) {
|
||||
return true;
|
||||
});
|
||||
|
||||
EXTEND(item.attrs, attrs);
|
||||
Object.assign(item.attrs, attrs);
|
||||
|
||||
if (styles.length) {
|
||||
item.attr('style').value = styles
|
||||
|
||||
3
node_modules/svgo/plugins/convertTransform.js
generated
vendored
3
node_modules/svgo/plugins/convertTransform.js
generated
vendored
@@ -22,7 +22,6 @@ exports.params = {
|
||||
};
|
||||
|
||||
var cleanupOutData = require('../lib/svgo/tools').cleanupOutData,
|
||||
EXTEND = require('whet.extend'),
|
||||
transform2js = require('./_transforms.js').transform2js,
|
||||
transformsMultiply = require('./_transforms.js').transformsMultiply,
|
||||
matrixToTransform = require('./_transforms.js').matrixToTransform,
|
||||
@@ -116,7 +115,7 @@ function definePrecision(data, params) {
|
||||
significantDigits = params.transformPrecision;
|
||||
|
||||
// Clone params so it don't affect other elements transformations.
|
||||
params = EXTEND({}, params);
|
||||
params = Object.assign({}, params);
|
||||
|
||||
// Limit transform precision with matrix one. Calculating with larger precision doesn't add any value.
|
||||
if (matrixData.length) {
|
||||
|
||||
171
node_modules/svgo/plugins/minifyStyles.js
generated
vendored
171
node_modules/svgo/plugins/minifyStyles.js
generated
vendored
@@ -1,45 +1,160 @@
|
||||
'use strict';
|
||||
|
||||
exports.type = 'perItem';
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = true;
|
||||
|
||||
exports.params = {
|
||||
svgo: {}
|
||||
};
|
||||
exports.description = 'minifies styles and removes unused styles based on usage data';
|
||||
|
||||
exports.description = 'minifies existing styles in svg';
|
||||
exports.params = {
|
||||
// ... CSSO options goes here
|
||||
|
||||
// additional
|
||||
usage: {
|
||||
force: false, // force to use usage data even if it unsafe (document contains <script> or on* attributes)
|
||||
ids: true,
|
||||
classes: true,
|
||||
tags: true
|
||||
}
|
||||
};
|
||||
|
||||
var csso = require('csso');
|
||||
|
||||
/**
|
||||
* Minifies styles (<style> element + style attribute) using svgo
|
||||
*
|
||||
* @param {Object} item current iteration item
|
||||
* @return {Boolean} if false, item will be filtered out
|
||||
* Minifies styles (<style> element + style attribute) using CSSO
|
||||
*
|
||||
* @author strarsis <strarsis@gmail.com>
|
||||
*/
|
||||
exports.fn = function(item, svgoOptions) {
|
||||
exports.fn = function(ast, options) {
|
||||
options = options || {};
|
||||
|
||||
if(item.elem) {
|
||||
if(item.isElem('style') && !item.isEmpty()) {
|
||||
var styleCss = item.content[0].text || item.content[0].cdata || [],
|
||||
DATA = styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0 ? 'cdata' : 'text';
|
||||
if(styleCss.length > 0) {
|
||||
var styleCssMinified = csso.minify(styleCss, svgoOptions);
|
||||
item.content[0][DATA] = styleCssMinified.css;
|
||||
}
|
||||
}
|
||||
var minifyOptionsForStylesheet = cloneObject(options);
|
||||
var minifyOptionsForAttribute = cloneObject(options);
|
||||
var elems = findStyleElems(ast);
|
||||
|
||||
if(item.hasAttr('style')) {
|
||||
var itemCss = item.attr('style').value;
|
||||
if(itemCss.length > 0) {
|
||||
var itemCssMinified = csso.minifyBlock(itemCss, svgoOptions);
|
||||
item.attr('style').value = itemCssMinified.css;
|
||||
}
|
||||
}
|
||||
minifyOptionsForStylesheet.usage = collectUsageData(ast, options);
|
||||
minifyOptionsForAttribute.usage = null;
|
||||
|
||||
elems.forEach(function(elem) {
|
||||
if (elem.isElem('style')) {
|
||||
// <style> element
|
||||
var styleCss = elem.content[0].text || elem.content[0].cdata || [];
|
||||
var DATA = styleCss.indexOf('>') >= 0 || styleCss.indexOf('<') >= 0 ? 'cdata' : 'text';
|
||||
|
||||
elem.content[0][DATA] = csso.minify(styleCss, minifyOptionsForStylesheet).css;
|
||||
} else {
|
||||
// style attribute
|
||||
var elemStyle = elem.attr('style').value;
|
||||
|
||||
elem.attr('style').value = csso.minifyBlock(elemStyle, minifyOptionsForAttribute).css;
|
||||
}
|
||||
});
|
||||
|
||||
return ast;
|
||||
};
|
||||
|
||||
function cloneObject(obj) {
|
||||
var result = {};
|
||||
|
||||
for (var key in obj) {
|
||||
result[key] = obj[key];
|
||||
}
|
||||
|
||||
return item;
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
function findStyleElems(ast) {
|
||||
|
||||
function walk(items, styles) {
|
||||
for (var i = 0; i < items.content.length; i++) {
|
||||
var item = items.content[i];
|
||||
|
||||
// go deeper
|
||||
if (item.content) {
|
||||
walk(item, styles);
|
||||
}
|
||||
|
||||
if (item.isElem('style') && !item.isEmpty()) {
|
||||
styles.push(item);
|
||||
} else if (item.isElem() && item.hasAttr('style')) {
|
||||
styles.push(item);
|
||||
}
|
||||
}
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
return walk(ast, []);
|
||||
}
|
||||
|
||||
function shouldFilter(options, name) {
|
||||
if ('usage' in options === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (options.usage && name in options.usage === false) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Boolean(options.usage && options.usage[name]);
|
||||
}
|
||||
|
||||
function collectUsageData(ast, options) {
|
||||
|
||||
function walk(items, usageData) {
|
||||
for (var i = 0; i < items.content.length; i++) {
|
||||
var item = items.content[i];
|
||||
|
||||
// go deeper
|
||||
if (item.content) {
|
||||
walk(item, usageData);
|
||||
}
|
||||
|
||||
if (item.isElem('script')) {
|
||||
safe = false;
|
||||
}
|
||||
|
||||
if (item.isElem()) {
|
||||
usageData.tags[item.elem] = true;
|
||||
|
||||
if (item.hasAttr('id')) {
|
||||
usageData.ids[item.attr('id').value] = true;
|
||||
}
|
||||
|
||||
if (item.hasAttr('class')) {
|
||||
item.attr('class').value.replace(/^\s+|\s+$/g, '').split(/\s+/).forEach(function(className) {
|
||||
usageData.classes[className] = true;
|
||||
});
|
||||
}
|
||||
|
||||
if (item.attrs && Object.keys(item.attrs).some(function(name) { return /^on/i.test(name); })) {
|
||||
safe = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return usageData;
|
||||
}
|
||||
|
||||
var safe = true;
|
||||
var usageData = {};
|
||||
var hasData = false;
|
||||
var rawData = walk(ast, {
|
||||
ids: Object.create(null),
|
||||
classes: Object.create(null),
|
||||
tags: Object.create(null)
|
||||
});
|
||||
|
||||
if (!safe && options.usage && options.usage.force) {
|
||||
safe = true;
|
||||
}
|
||||
|
||||
for (var key in rawData) {
|
||||
if (shouldFilter(options, key)) {
|
||||
usageData[key] = Object.keys(rawData[key]);
|
||||
hasData = true;
|
||||
}
|
||||
}
|
||||
|
||||
return safe && hasData ? usageData : null;
|
||||
}
|
||||
|
||||
53
node_modules/svgo/plugins/removeAttrs.js
generated
vendored
53
node_modules/svgo/plugins/removeAttrs.js
generated
vendored
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
var ELEM_SEP = ':';
|
||||
var DEFAULT_SEPARATOR = ':';
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
@@ -9,18 +9,27 @@ exports.active = false;
|
||||
exports.description = 'removes specified attributes';
|
||||
|
||||
exports.params = {
|
||||
elemSeparator: DEFAULT_SEPARATOR,
|
||||
preserveCurrentColor: false,
|
||||
attrs: []
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove attributes
|
||||
*
|
||||
* @param elemSeparator
|
||||
* format: string
|
||||
*
|
||||
* @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
|
||||
*
|
||||
* examples:
|
||||
*
|
||||
@@ -33,6 +42,10 @@ exports.params = {
|
||||
* ---
|
||||
* attrs: 'path:fill'
|
||||
*
|
||||
* > remove fill attribute on path element where value is none
|
||||
* ---
|
||||
* attrs: 'path:fill:none'
|
||||
*
|
||||
*
|
||||
* > remove all fill and stroke attribute
|
||||
* ---
|
||||
@@ -52,6 +65,10 @@ exports.params = {
|
||||
*
|
||||
* attrs: '.*:(fill|stroke)'
|
||||
*
|
||||
* [is same as]
|
||||
*
|
||||
* attrs: '.*:(fill|stroke):.*'
|
||||
*
|
||||
*
|
||||
* > remove all stroke related attributes
|
||||
* ----
|
||||
@@ -65,24 +82,29 @@ exports.params = {
|
||||
* @author Benny Schudel
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
// wrap into an array if params is not
|
||||
if (!Array.isArray(params.attrs)) {
|
||||
params.attrs = [params.attrs];
|
||||
}
|
||||
|
||||
if (item.isElem()) {
|
||||
var elemSeparator = typeof params.elemSeparator == 'string' ? params.elemSeparator : DEFAULT_SEPARATOR;
|
||||
var preserveCurrentColor = typeof params.preserveCurrentColor == 'boolean' ? params.preserveCurrentColor : false;
|
||||
|
||||
// prepare patterns
|
||||
var patterns = params.attrs.map(function(pattern) {
|
||||
|
||||
// apply to all elements if specifc element is omitted
|
||||
if (pattern.indexOf(ELEM_SEP) === -1) {
|
||||
pattern = ['.*', ELEM_SEP, pattern].join('');
|
||||
// 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, 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
|
||||
return pattern.split(ELEM_SEP)
|
||||
// create regexps for element, attribute name, and attribute value
|
||||
return pattern.split(elemSeparator)
|
||||
.map(function(value) {
|
||||
|
||||
// adjust single * to match anything
|
||||
@@ -102,10 +124,19 @@ exports.fn = function(item, params) {
|
||||
// loop attributes
|
||||
item.eachAttr(function(attr) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
6
node_modules/svgo/plugins/removeDesc.js
generated
vendored
6
node_modules/svgo/plugins/removeDesc.js
generated
vendored
@@ -5,12 +5,12 @@ exports.type = 'perItem';
|
||||
exports.active = true;
|
||||
|
||||
exports.params = {
|
||||
removeAny: false
|
||||
removeAny: true
|
||||
};
|
||||
|
||||
exports.description = 'removes <desc> (only non-meaningful by default)';
|
||||
exports.description = 'removes <desc>';
|
||||
|
||||
var standardDescs = /^Created with/;
|
||||
var standardDescs = /^(Created with|Created using)/;
|
||||
|
||||
/**
|
||||
* Removes <desc>.
|
||||
|
||||
2
node_modules/svgo/plugins/removeDimensions.js
generated
vendored
2
node_modules/svgo/plugins/removeDimensions.js
generated
vendored
@@ -4,7 +4,7 @@ exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'removes width and height in presence of viewBox';
|
||||
exports.description = 'removes width and height in presence of viewBox (opposite to removeViewBox, disable it first)';
|
||||
|
||||
/**
|
||||
* Remove width/height attributes when a viewBox attribute is present.
|
||||
|
||||
9
node_modules/svgo/plugins/removeHiddenElems.js
generated
vendored
9
node_modules/svgo/plugins/removeHiddenElems.js
generated
vendored
@@ -7,6 +7,7 @@ exports.active = true;
|
||||
exports.description = 'removes hidden elements (zero sized, with absent attributes)';
|
||||
|
||||
exports.params = {
|
||||
isHidden: true,
|
||||
displayNone: true,
|
||||
opacity0: true,
|
||||
circleR0: true,
|
||||
@@ -44,9 +45,15 @@ var regValidPath = /M\s*(?:[-+]?(?:\d*\.\d+|\d+(?:\.|(?!\.)))([eE][-+]?\d+)?(?!\
|
||||
*
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
exports.fn = function (item, params) {
|
||||
|
||||
if (item.elem) {
|
||||
// Removes hidden elements
|
||||
// https://www.w3schools.com/cssref/pr_class_visibility.asp
|
||||
if (
|
||||
params.isHidden &&
|
||||
item.hasAttr('visibility', 'hidden')
|
||||
) return false;
|
||||
|
||||
// display="none"
|
||||
//
|
||||
|
||||
9
node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js
generated
vendored
9
node_modules/svgo/plugins/removeNonInheritableGroupAttrs.js
generated
vendored
@@ -8,7 +8,7 @@ exports.description = 'removes non-inheritable group’s presentational attribut
|
||||
|
||||
var inheritableAttrs = require('./_collections').inheritableAttrs,
|
||||
attrsGroups = require('./_collections').attrsGroups,
|
||||
excludedAttrs = ['display', 'opacity'];
|
||||
applyGroups = require('./_collections').presentationNonInheritableGroupAttrs;
|
||||
|
||||
/**
|
||||
* Remove non-inheritable group's "presentation" attributes.
|
||||
@@ -25,11 +25,8 @@ exports.fn = function(item) {
|
||||
item.eachAttr(function(attr) {
|
||||
if (
|
||||
~attrsGroups.presentation.indexOf(attr.name) &&
|
||||
~attrsGroups.graphicalEvent.indexOf(attr.name) &&
|
||||
~attrsGroups.core.indexOf(attr.name) &&
|
||||
~attrsGroups.conditionalProcessing.indexOf(attr.name) &&
|
||||
!~excludedAttrs.indexOf(attr.name) &&
|
||||
!~inheritableAttrs.indexOf(attr.name)
|
||||
!~inheritableAttrs.indexOf(attr.name) &&
|
||||
!~applyGroups.indexOf(attr.name)
|
||||
) {
|
||||
item.removeAttr(attr.name);
|
||||
}
|
||||
|
||||
5
node_modules/svgo/plugins/removeTitle.js
generated
vendored
5
node_modules/svgo/plugins/removeTitle.js
generated
vendored
@@ -2,13 +2,12 @@
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes <title> (disabled by default)';
|
||||
exports.description = 'removes <title>';
|
||||
|
||||
/**
|
||||
* Remove <title>.
|
||||
* Disabled by default cause it may be used for accessibility.
|
||||
*
|
||||
* https://developer.mozilla.org/en-US/docs/Web/SVG/Element/title
|
||||
*
|
||||
|
||||
15
node_modules/svgo/plugins/removeUnknownsAndDefaults.js
generated
vendored
15
node_modules/svgo/plugins/removeUnknownsAndDefaults.js
generated
vendored
@@ -11,7 +11,9 @@ exports.params = {
|
||||
unknownAttrs: true,
|
||||
defaultAttrs: true,
|
||||
uselessOverrides: true,
|
||||
keepDataAttrs: true
|
||||
keepDataAttrs: true,
|
||||
keepAriaAttrs: true,
|
||||
keepRoleAttr: false
|
||||
};
|
||||
|
||||
var collections = require('./_collections'),
|
||||
@@ -19,7 +21,8 @@ var collections = require('./_collections'),
|
||||
attrsGroups = collections.attrsGroups,
|
||||
elemsGroups = collections.elemsGroups,
|
||||
attrsGroupsDefaults = collections.attrsGroupsDefaults,
|
||||
attrsInheritable = collections.inheritableAttrs;
|
||||
attrsInheritable = collections.inheritableAttrs,
|
||||
applyGroups = collections.presentationNonInheritableGroupAttrs;
|
||||
|
||||
// collect and extend all references
|
||||
for (var elem in elems) {
|
||||
@@ -105,7 +108,9 @@ exports.fn = function(item, params) {
|
||||
if (
|
||||
attr.name !== 'xmlns' &&
|
||||
(attr.prefix === 'xml' || !attr.prefix) &&
|
||||
(!params.keepDataAttrs || attr.name.indexOf('data-') != 0)
|
||||
(!params.keepDataAttrs || attr.name.indexOf('data-') != 0) &&
|
||||
(!params.keepAriaAttrs || attr.name.indexOf('aria-') != 0) &&
|
||||
(!params.keepRoleAttr || attr.name != 'role')
|
||||
) {
|
||||
if (
|
||||
// unknown attrs
|
||||
@@ -116,6 +121,7 @@ exports.fn = function(item, params) {
|
||||
// attrs with default values
|
||||
(
|
||||
params.defaultAttrs &&
|
||||
!item.hasAttr('id') &&
|
||||
elems[elem].defaults &&
|
||||
elems[elem].defaults[attr.name] === attr.value && (
|
||||
attrsInheritable.indexOf(attr.name) < 0 ||
|
||||
@@ -125,7 +131,8 @@ exports.fn = function(item, params) {
|
||||
// useless overrides
|
||||
(
|
||||
params.uselessOverrides &&
|
||||
attr.name !== 'transform' &&
|
||||
!item.hasAttr('id') &&
|
||||
applyGroups.indexOf(attr.name) < 0 &&
|
||||
attrsInheritable.indexOf(attr.name) > -1 &&
|
||||
item.parentNode.computedAttr(attr.name, attr.value)
|
||||
)
|
||||
|
||||
26
node_modules/svgo/plugins/removeUselessDefs.js
generated
vendored
26
node_modules/svgo/plugins/removeUselessDefs.js
generated
vendored
@@ -6,8 +6,7 @@ exports.active = true;
|
||||
|
||||
exports.description = 'removes elements in <defs> without id';
|
||||
|
||||
var nonRendering = require('./_collections').elemsGroups.nonRendering,
|
||||
defs;
|
||||
var nonRendering = require('./_collections').elemsGroups.nonRendering;
|
||||
|
||||
/**
|
||||
* Removes content of defs and properties that aren't rendered directly without ids.
|
||||
@@ -21,9 +20,10 @@ exports.fn = function(item) {
|
||||
|
||||
if (item.isElem('defs')) {
|
||||
|
||||
defs = item;
|
||||
item.content = (item.content || []).reduce(getUsefulItems, []);
|
||||
|
||||
if (item.content) {
|
||||
item.content = getUsefulItems(item, []);
|
||||
}
|
||||
|
||||
if (item.isEmpty()) return false;
|
||||
|
||||
} else if (item.isElem(nonRendering) && !item.hasAttr('id')) {
|
||||
@@ -34,18 +34,20 @@ exports.fn = function(item) {
|
||||
|
||||
};
|
||||
|
||||
function getUsefulItems(usefulItems, item) {
|
||||
function getUsefulItems(item, usefulItems) {
|
||||
|
||||
if (item.hasAttr('id') || item.isElem('style')) {
|
||||
item.content.forEach(function(child) {
|
||||
if (child.hasAttr('id') || child.isElem('style')) {
|
||||
|
||||
usefulItems.push(item);
|
||||
item.parentNode = defs;
|
||||
usefulItems.push(child);
|
||||
child.parentNode = item;
|
||||
|
||||
} else if (!item.isEmpty()) {
|
||||
} else if (!child.isEmpty()) {
|
||||
|
||||
item.content.reduce(getUsefulItems, usefulItems);
|
||||
child.content = getUsefulItems(child, usefulItems);
|
||||
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return usefulItems;
|
||||
}
|
||||
|
||||
20
node_modules/svgo/plugins/removeUselessStrokeAndFill.js
generated
vendored
20
node_modules/svgo/plugins/removeUselessStrokeAndFill.js
generated
vendored
@@ -8,14 +8,15 @@ exports.description = 'removes useless stroke and fill attributes';
|
||||
|
||||
exports.params = {
|
||||
stroke: true,
|
||||
fill: true
|
||||
fill: true,
|
||||
removeNone: false,
|
||||
hasStyleOrScript: false
|
||||
};
|
||||
|
||||
var shape = require('./_collections').elemsGroups.shape,
|
||||
regStrokeProps = /^stroke/,
|
||||
regFillProps = /^fill-/,
|
||||
styleOrScript = ['style', 'script'],
|
||||
hasStyleOrScript = false;
|
||||
styleOrScript = ['style', 'script'];
|
||||
|
||||
/**
|
||||
* Remove useless stroke and fill attrs.
|
||||
@@ -27,12 +28,12 @@ var shape = require('./_collections').elemsGroups.shape,
|
||||
* @author Kir Belevich
|
||||
*/
|
||||
exports.fn = function(item, params) {
|
||||
|
||||
|
||||
if (item.isElem(styleOrScript)) {
|
||||
hasStyleOrScript = true;
|
||||
params.hasStyleOrScript = true;
|
||||
}
|
||||
|
||||
if (!hasStyleOrScript && item.isElem(shape) && !item.computedAttr('id')) {
|
||||
if (!params.hasStyleOrScript && item.isElem(shape) && !item.computedAttr('id')) {
|
||||
|
||||
var stroke = params.stroke && item.computedAttr('stroke'),
|
||||
fill = params.fill && !item.computedAttr('fill', 'none');
|
||||
@@ -87,6 +88,13 @@ exports.fn = function(item, params) {
|
||||
}
|
||||
}
|
||||
|
||||
if (params.removeNone &&
|
||||
(!stroke || item.hasAttr('stroke') && item.attr('stroke').value=='none') &&
|
||||
(!fill || item.hasAttr('fill') && item.attr('fill').value=='none')) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
23
node_modules/svgo/plugins/removeViewBox.js
generated
vendored
23
node_modules/svgo/plugins/removeViewBox.js
generated
vendored
@@ -2,12 +2,11 @@
|
||||
|
||||
exports.type = 'perItem';
|
||||
|
||||
exports.active = false;
|
||||
exports.active = true;
|
||||
|
||||
exports.description = 'removes viewBox attribute when possible (disabled by default)';
|
||||
exports.description = 'removes viewBox attribute when possible';
|
||||
|
||||
var regViewBox = /^0\s0\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)\s([\-+]?\d*\.?\d+([eE][\-+]?\d+)?)$/,
|
||||
viewBoxElems = ['svg', 'pattern'];
|
||||
var viewBoxElems = ['svg', 'pattern', 'symbol'];
|
||||
|
||||
/**
|
||||
* Remove viewBox attr which coincides with a width/height box.
|
||||
@@ -33,15 +32,15 @@ exports.fn = function(item) {
|
||||
item.hasAttr('height')
|
||||
) {
|
||||
|
||||
var match = item.attr('viewBox').value.match(regViewBox);
|
||||
var nums = item.attr('viewBox').value.split(/[ ,]+/g);
|
||||
|
||||
if (match) {
|
||||
if (
|
||||
item.attr('width').value === match[1] &&
|
||||
item.attr('height').value === match[3]
|
||||
) {
|
||||
item.removeAttr('viewBox');
|
||||
}
|
||||
if (
|
||||
nums[0] === '0' &&
|
||||
nums[1] === '0' &&
|
||||
item.attr('width').value.replace(/px$/, '') === nums[2] && // could use parseFloat too
|
||||
item.attr('height').value.replace(/px$/, '') === nums[3]
|
||||
) {
|
||||
item.removeAttr('viewBox');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
13
node_modules/svgo/plugins/sortAttrs.js
generated
vendored
13
node_modules/svgo/plugins/sortAttrs.js
generated
vendored
@@ -30,7 +30,8 @@ exports.fn = function(item, params) {
|
||||
|
||||
var attrs = [],
|
||||
sorted = {},
|
||||
orderlen = params.order.length + 1;
|
||||
orderlen = params.order.length + 1,
|
||||
xmlnsOrder = params.xmlnsOrder || 'front';
|
||||
|
||||
if (item.elem) {
|
||||
|
||||
@@ -41,10 +42,12 @@ exports.fn = function(item, params) {
|
||||
attrs.sort(function(a, b) {
|
||||
if (a.prefix != b.prefix) {
|
||||
// xmlns attributes implicitly have the prefix xmlns
|
||||
if (a.prefix == 'xmlns')
|
||||
return -1;
|
||||
if (b.prefix == 'xmlns')
|
||||
return 1;
|
||||
if (xmlnsOrder == 'front') {
|
||||
if (a.prefix == 'xmlns')
|
||||
return -1;
|
||||
if (b.prefix == 'xmlns')
|
||||
return 1;
|
||||
}
|
||||
return a.prefix < b.prefix ? -1 : 1;
|
||||
}
|
||||
|
||||
|
||||
327
node_modules/svgo/plugins/transformsWithOnePath.js
generated
vendored
327
node_modules/svgo/plugins/transformsWithOnePath.js
generated
vendored
@@ -1,327 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/*
|
||||
* Thanks to http://fontello.com project for sponsoring this plugin
|
||||
*/
|
||||
|
||||
exports.type = 'full';
|
||||
|
||||
exports.active = false;
|
||||
|
||||
exports.description = 'performs a set of operations on SVG with one path inside (disabled by default)';
|
||||
|
||||
exports.params = {
|
||||
// width and height to resize SVG and rescale inner Path
|
||||
width: false,
|
||||
height: false,
|
||||
|
||||
// scale inner Path without resizing SVG
|
||||
scale: false,
|
||||
|
||||
// shiftX/Y inner Path
|
||||
shiftX: false,
|
||||
shiftY: false,
|
||||
|
||||
// crop SVG width along the real width of inner Path
|
||||
hcrop: false,
|
||||
|
||||
// vertical center inner Path inside SVG height
|
||||
vcenter: false,
|
||||
|
||||
// stringify params
|
||||
floatPrecision: 3,
|
||||
leadingZero: true,
|
||||
negativeExtraSpace: true
|
||||
};
|
||||
|
||||
var _path = require('./_path.js'),
|
||||
relative2absolute = _path.relative2absolute,
|
||||
computeCubicBoundingBox = _path.computeCubicBoundingBox,
|
||||
computeQuadraticBoundingBox = _path.computeQuadraticBoundingBox,
|
||||
applyTransforms = _path.applyTransforms,
|
||||
js2path = _path.js2path,
|
||||
path2js = _path.path2js,
|
||||
EXTEND = require('whet.extend');
|
||||
|
||||
exports.fn = function(data, params) {
|
||||
|
||||
data.content.forEach(function(item) {
|
||||
|
||||
// only for SVG with one Path inside
|
||||
if (item.isElem('svg') &&
|
||||
item.content.length === 1 &&
|
||||
item.content[0].isElem('path')
|
||||
) {
|
||||
|
||||
var svgElem = item,
|
||||
pathElem = svgElem.content[0],
|
||||
// get absoluted Path data
|
||||
path = relative2absolute(EXTEND(true, [], path2js(pathElem))),
|
||||
xs = [],
|
||||
ys = [],
|
||||
cubicСontrolPoint = [0, 0],
|
||||
quadraticСontrolPoint = [0, 0],
|
||||
lastPoint = [0, 0],
|
||||
cubicBoundingBox,
|
||||
quadraticBoundingBox,
|
||||
i,
|
||||
segment;
|
||||
|
||||
path.forEach(function(pathItem) {
|
||||
|
||||
// ML
|
||||
if ('ML'.indexOf(pathItem.instruction) > -1) {
|
||||
|
||||
for (i = 0; i < pathItem.data.length; i++) {
|
||||
if (i % 2 === 0) {
|
||||
xs.push(pathItem.data[i]);
|
||||
} else {
|
||||
ys.push(pathItem.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
lastPoint = cubicСontrolPoint = quadraticСontrolPoint = pathItem.data.slice(-2);
|
||||
|
||||
// H
|
||||
} else if (pathItem.instruction === 'H') {
|
||||
|
||||
pathItem.data.forEach(function(d) {
|
||||
xs.push(d);
|
||||
});
|
||||
|
||||
lastPoint[0] = cubicСontrolPoint[0] = quadraticСontrolPoint[0] = pathItem.data[pathItem.data.length - 2];
|
||||
|
||||
// V
|
||||
} else if (pathItem.instruction === 'V') {
|
||||
|
||||
pathItem.data.forEach(function(d) {
|
||||
ys.push(d);
|
||||
});
|
||||
|
||||
lastPoint[1] = cubicСontrolPoint[1] = quadraticСontrolPoint[1] = pathItem.data[pathItem.data.length - 1];
|
||||
|
||||
// C
|
||||
} else if (pathItem.instruction === 'C') {
|
||||
|
||||
for (i = 0; i < pathItem.data.length; i += 6) {
|
||||
|
||||
segment = pathItem.data.slice(i, i + 6);
|
||||
|
||||
cubicBoundingBox = computeCubicBoundingBox.apply(this, lastPoint.concat(segment));
|
||||
|
||||
xs.push(cubicBoundingBox.minx);
|
||||
xs.push(cubicBoundingBox.maxx);
|
||||
|
||||
ys.push(cubicBoundingBox.miny);
|
||||
ys.push(cubicBoundingBox.maxy);
|
||||
|
||||
// reflected control point for the next possible S
|
||||
cubicСontrolPoint = [
|
||||
2 * segment[4] - segment[2],
|
||||
2 * segment[5] - segment[3]
|
||||
];
|
||||
|
||||
lastPoint = segment.slice(-2);
|
||||
|
||||
}
|
||||
|
||||
// S
|
||||
} else if (pathItem.instruction === 'S') {
|
||||
|
||||
for (i = 0; i < pathItem.data.length; i += 4) {
|
||||
|
||||
segment = pathItem.data.slice(i, i + 4);
|
||||
|
||||
cubicBoundingBox = computeCubicBoundingBox.apply(this, lastPoint.concat(cubicСontrolPoint).concat(segment));
|
||||
|
||||
xs.push(cubicBoundingBox.minx);
|
||||
xs.push(cubicBoundingBox.maxx);
|
||||
|
||||
ys.push(cubicBoundingBox.miny);
|
||||
ys.push(cubicBoundingBox.maxy);
|
||||
|
||||
// reflected control point for the next possible S
|
||||
cubicСontrolPoint = [
|
||||
2 * segment[2] - cubicСontrolPoint[0],
|
||||
2 * segment[3] - cubicСontrolPoint[1],
|
||||
];
|
||||
|
||||
lastPoint = segment.slice(-2);
|
||||
|
||||
}
|
||||
|
||||
// Q
|
||||
} else if (pathItem.instruction === 'Q') {
|
||||
|
||||
for (i = 0; i < pathItem.data.length; i += 4) {
|
||||
|
||||
segment = pathItem.data.slice(i, i + 4);
|
||||
|
||||
quadraticBoundingBox = computeQuadraticBoundingBox.apply(this, lastPoint.concat(segment));
|
||||
|
||||
xs.push(quadraticBoundingBox.minx);
|
||||
xs.push(quadraticBoundingBox.maxx);
|
||||
|
||||
ys.push(quadraticBoundingBox.miny);
|
||||
ys.push(quadraticBoundingBox.maxy);
|
||||
|
||||
// reflected control point for the next possible T
|
||||
quadraticСontrolPoint = [
|
||||
2 * segment[2] - segment[0],
|
||||
2 * segment[3] - segment[1]
|
||||
];
|
||||
|
||||
lastPoint = segment.slice(-2);
|
||||
|
||||
}
|
||||
|
||||
// S
|
||||
} else if (pathItem.instruction === 'T') {
|
||||
|
||||
for (i = 0; i < pathItem.data.length; i += 2) {
|
||||
|
||||
segment = pathItem.data.slice(i, i + 2);
|
||||
|
||||
quadraticBoundingBox = computeQuadraticBoundingBox.apply(this, lastPoint.concat(quadraticСontrolPoint).concat(segment));
|
||||
|
||||
xs.push(quadraticBoundingBox.minx);
|
||||
xs.push(quadraticBoundingBox.maxx);
|
||||
|
||||
ys.push(quadraticBoundingBox.miny);
|
||||
ys.push(quadraticBoundingBox.maxy);
|
||||
|
||||
// reflected control point for the next possible T
|
||||
quadraticСontrolPoint = [
|
||||
2 * segment[0] - quadraticСontrolPoint[0],
|
||||
2 * segment[1] - quadraticСontrolPoint[1]
|
||||
];
|
||||
|
||||
lastPoint = segment.slice(-2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
var xmin = Math.min.apply(this, xs).toFixed(params.floatPrecision),
|
||||
xmax = Math.max.apply(this, xs).toFixed(params.floatPrecision),
|
||||
ymin = Math.min.apply(this, ys).toFixed(params.floatPrecision),
|
||||
ymax = Math.max.apply(this, ys).toFixed(params.floatPrecision),
|
||||
svgWidth = +svgElem.attr('width').value,
|
||||
svgHeight = +svgElem.attr('height').value,
|
||||
realWidth = Math.round(xmax - xmin),
|
||||
realHeight = Math.round(ymax - ymin),
|
||||
transform = '',
|
||||
scale;
|
||||
|
||||
// width & height
|
||||
if (params.width && params.height) {
|
||||
|
||||
scale = Math.min(params.width / svgWidth, params.height / svgHeight);
|
||||
|
||||
realWidth = realWidth * scale;
|
||||
realHeight = realHeight * scale;
|
||||
|
||||
svgWidth = svgElem.attr('width').value = params.width;
|
||||
svgHeight = svgElem.attr('height').value = params.height;
|
||||
|
||||
transform += ' scale(' + scale + ')';
|
||||
|
||||
// width
|
||||
} else if (params.width && !params.height) {
|
||||
|
||||
scale = params.width / svgWidth;
|
||||
|
||||
realWidth = realWidth * scale;
|
||||
realHeight = realHeight * scale;
|
||||
|
||||
svgWidth = svgElem.attr('width').value = params.width;
|
||||
svgHeight = svgElem.attr('height').value = svgHeight * scale;
|
||||
|
||||
transform += ' scale(' + scale + ')';
|
||||
|
||||
// height
|
||||
} else if (params.height && !params.width) {
|
||||
|
||||
scale = params.height / svgHeight;
|
||||
|
||||
realWidth = realWidth * scale;
|
||||
realHeight = realHeight * scale;
|
||||
|
||||
svgWidth = svgElem.attr('width').value = svgWidth * scale;
|
||||
svgHeight = svgElem.attr('height').value = params.height;
|
||||
|
||||
transform += ' scale(' + scale + ')';
|
||||
|
||||
}
|
||||
|
||||
// shiftX
|
||||
if (params.shiftX) {
|
||||
transform += ' translate(' + realWidth * params.shiftX + ', 0)';
|
||||
}
|
||||
|
||||
// shiftY
|
||||
if (params.shiftY) {
|
||||
transform += ' translate(0, ' + realHeight * params.shiftY + ')';
|
||||
}
|
||||
|
||||
// scale
|
||||
if (params.scale) {
|
||||
scale = params.scale;
|
||||
|
||||
var shiftX = svgWidth / 2,
|
||||
shiftY = svgHeight / 2;
|
||||
|
||||
realWidth = realWidth * scale;
|
||||
realHeight = realHeight * scale;
|
||||
|
||||
if (params.shiftX || params.shiftY) {
|
||||
transform += ' scale(' + scale + ')';
|
||||
} else {
|
||||
transform += ' translate(' + shiftX + ' ' + shiftY + ') scale(' + scale + ') translate(-' + shiftX + ' -' + shiftY + ')';
|
||||
}
|
||||
}
|
||||
|
||||
// hcrop
|
||||
if (params.hcrop) {
|
||||
transform += ' translate(' + (-xmin) + ' 0)';
|
||||
|
||||
svgElem.attr('width').value = realWidth;
|
||||
}
|
||||
|
||||
// vcenter
|
||||
if (params.vcenter) {
|
||||
transform += ' translate(0 ' + (((svgHeight - realHeight) / 2) - ymin) + ')';
|
||||
}
|
||||
|
||||
if (transform) {
|
||||
pathElem.addAttr({
|
||||
name: 'transform',
|
||||
prefix: '',
|
||||
local: 'transform',
|
||||
value: transform
|
||||
});
|
||||
|
||||
path = applyTransforms(pathElem, pathElem.pathJS, true, params.floatPrecision);
|
||||
|
||||
// transformed data rounding
|
||||
path.forEach(function(pathItem) {
|
||||
if (pathItem.data) {
|
||||
pathItem.data = pathItem.data.map(function(num) {
|
||||
return +num.toFixed(params.floatPrecision);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// save new
|
||||
js2path(pathElem, path, params);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return data;
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user