SVGs can have the same presentation attribute declared redundantly in
both the node attributes and `<style>` tag.
This wouldn't break anything, but we can shave off a few more bytes by
dropping the attribute in this case.
When running this plugin on an SVG with an empty block in the CSS, it
would apply it to the matched elements by adding an empty `style`
attribute. See the test for an example.
This resolves that by just dropping the declaration if it's empty.
I also had some chores pending which were trivial individually, I opted
to incorporate them here as well.
* In JSDocs, use the nullable syntax as it's more concise and familiar
from TypeScript usage.
* discord → Discord (proper nouns should match capitalization)
* Use actions/checkout v4 instead of v2
Detects if a redundant linearGradient or radialGradient is used with
only a single stop, which effectively means a solid color.
If this is found, just remove the gradient and replace references to it
with the color of the first and only stop defined.
The space is optional between transform functions in the `transform`
attribute and similar properties. This just omits the space as a
micro-optimization.
This does not add new tests is the scenario is covered adequately in
existing tests.
Also refactors js2transform to avoid concatenating in a loop.
When running into a multi-class selector with `inlineStyles`, it would
only remove the first class of the selector instead of all of them.
This iterates the classes in the selector instead of only taking the
first. Also performs some minor refactors.
Style property names are case-insensitive, for example `fill`, `FILL`,
and `FiLl` are all valid but refer to the same property. So when
inlining styles, we compare the lowercase strings and only use the last
instance of the property rather than embed them all.
Fixes a bug where the reusePaths plugin would reuse the node ID that
it's optimizing, but that ID was also referenced in a href elsewhere
in the document, so it unintentionally applied the path to other nodes.
The regression-test GitHub Action was failing for all pull requests due
to not handling the gzipped archive properly.
This resolved it by piping the response body to zlib#createGunzip
first. Also updates the relevant dependencies.
Signed-off-by: Seth Falco <seth@falco.fun>
Co-authored-by: strarsis <strarsis@gmail.com>
Co-authored-by: Bogdan Chadkin <trysound@yandex.ru>
- applyTransforms is prepared to be a separate plugin, in v3 I will
remove it from convertPathData
- migrated to tsdoc
- removed optimisation with stroke-width inside id (still not idea how
it worked)
- added deoptimisation when id is on element to fix redefining in `<use>`
Note: review with hidden whitespaces
This is a big one
- got rid from another closestByName usage
- delegated removing empty defs elements to removeEmptyContainers plugin
- got rid from all css-tools usages (most inlineStyles code was there
for some reason)
- combined a few loops
- fixed useMqs option (I would remove it in v3 for simplicity as it
seems nobody use it)
`prefixIds` plugin currently breaks url()-links inside `style` attributes:
```javascript
optimize(
`<g style="fill:url(#brush-id);stroke:url(#pen-id)"/>`,
{ plugins: ['prefixIds'] }
).data
```
will generate `<g style=""/>`. Seems like `prefixIds` assumes that attribute's whole value might be `url()`, but this is not the case for the `style` attribute.
This fix solves the issue by preserving all attribute's content other than #id inside url(). It also adds some more tests for the `prefixIds` plugin.
nanocolors checks for --color and --no-color flags to force or disable
output coloring. Which can be used instead of strip-ansi package which
btw introduced vulnerability recently.
- covered with tsdoc
- replace another closestByName usage with visitSkip symbol to skip
subtree instead of skipping element by ancestor
Better review with hidden whitespaces as most code just got bigger indent.
Ref https://github.com/svg/svgo/issues/1579
In config of course. Projects with type:module can now use modules to
export config
```js
export default {
plugins: []
}
```
Also added support for resolving svgo.config.mjs and svgo.config.cjs.
Moved loadConfig tests to svgo-node tests.
mjs test is skipped for now in node 10, just don't use modules there
- covered with tsdoc
- migrated to visitor plugin api
- slightly simplified (hope so) logic by avoiding loop over order array
in every compare function call
- rewrote tests
Ref https://github.com/svg/svgo/issues/1499
- migrated to visitor plugin api
- covered with tsdoc
- made the plugin idempotent as requested a few times
Now even manually running svgo a few times will not duplicate
prefix in ids and classes
- run each plugin test twice to see which plugin need to run many times
ideally idempotent plugins will allow to get rid of multipass option in v3
Old SVGO errors were not very helpful. Packages like cssnano
(postcss-svgo) had to deal with a lot of issues which are hard to debug
with old errors.
```
Error: Error in parsing SVG: Unquoted attribute value
Line: 1
Column: 29
Char: 6
File: input.svg
```
New errors are more informative and may solve many struggles
```
Error: SvgoParserError: input.svg:2:29: Unquoted attribute value
1 | <svg viewBox="0 0 120 120">
> 2 | <circle fill="#ff0000" cx=60.444444" cy="60" r="50"/>
| ^
3 | </svg>
4 |
```
The logic is a little messy. Will be better when we drop node 12 support
and use optional chaining.
- migrated to visitor plugin api
- covered with types
- get rid from patching params as plugin state
- replaced many node.computedAttr() with style manager
- enabled and fixed removeNone param test (was merged as muted back in 2017)
- added ability to return null and not run visitor in plugins
- migrated to visitor plugin api; combination of enter and exit helped
to fit into single traverse
- got rid from the only node.clone() usage in the project so no need to
reimplement it
- the logic is a bit simplified
- refactored with visitor plugin api
- covered with types
- replaced parentNode traverse with visitSkip symbol
- replaced regex path parser with parsePathData
- get rid from global state which lead test case to invalid state