svgo
svgo copied to clipboard
Add replaceUse plugin
This plugin replaces all <use> elements with the nodes they clone and removes the top-level xlink attribute. While this doesn't "optimize" the SVG, it allows the contents to be used in SVG sprites within <symbol> elements. This plugin is best used in conjunction with removeUselessDefs.
This is a good plugins! I probably will use it in my project!
But Im suggesting to make this plugin being executed before the removeUselessDefs plugins, otherwise it will just duplicate the path after removing the <use> tag
@bbqaaq Great call. I almost always run with multipass enabled, so I didn't notice. I've moved it before removeUselessDefs.
Hi, I was testing this plugin and I found several bugs:
- It is removing necessary IDs (remove line 22)
- The tag use can have some attributes, unfortunately we cannot copy it inside the object being moved, perhaps it is best to use a new group and some transformations
- It ignores all defined object outside defs (yes, it is possible to do so with a svg)
@TiagoDinisFonseca I've addressed those bugs. Thanks for reporting them.
Regarding the <use> attributes, I changed the <use> tag into a group as per your suggestion, and my tests show equivalent behavior between <use> and <g>. However, please verify that your tests work as expected.
These fixes mean the plugin is no longer complimented by removeUselessDefs as it achieves the desired effect on its own.
Unfortunately, this is not true. The
As a user I do support adding this plugin as a optional one as I am useful with this.
In my project I got some SVGs with <use> and <defs> which is annoying to me
I have gone through this plugin and it works quite fine with the SVGs.
@TiagoDinisFonseca @tshedor any updates here? I'd really like to use this plugin.
I'd guess you should move the attributes from use to the path and not the
@GreLI can we prioritize this?
what would you need in order to get this merged?
@lifeiscontent At the time I was interested on this because it could be useful for me. It turns out, I was wrong. Therefore, I did not care to solve its problems. Sorry for that, eventually I can do it when I have the time to run this on my personal PC.
But you can solve it: 1- Your solution is not good enough, you never know what is inside, it could be a second group. 2- I guess that attributes x and y can be transformed into some translation (x,y) => transform="translation(x, y)" 3- What about width and height??? I feel bad about erasing some fields just because I do not understand them. 3.1 - There is a solution for this: we erase those fields... if this is a problem, this will be a bug in the future (I don't like this attitude, but perhaps it is ok)
Does this need to be absolutely perfect to be considered for addition? This would be very useful for me in it's current state
Rewritten to use the latest csstree api:
exports.fn = () => {
const defs = new Map;
const used = new Set;
return {
element: {
enter(node, parentNode) {
if (node.name === 'svg') {
delete node.attributes['xmlns:xlink'];
return
}
if (parentNode.name === 'defs') {
defs.set('#' + node.attributes.id, node);
return;
}
if (node.name === 'use') {
const id = node.attributes.href || node.attributes['xlink:href'];
const def = defs.get(id);
if (!def) {
console.warn(`Could not find definition for ${id}`);
return;
}
delete node.attributes['xlink:href'];
delete node.attributes['href'];
node.name = 'g';
node.children = [...def.children];
used.add(def);
}
},
},
root: {
exit(root) {
const defs = querySelector(root, 'defs');
if (defs) {
defs.children = defs.children.filter(node => !used.has(node));
if (!defs.children.length) {
defs.parentNode.children = defs.parentNode.children.filter(node => node !== defs);
}
}
}
}
}
}
@tshedor, @bbqaaq, @TiagoDinisFonseca, @lifeiscontent, @tommoor, @akre54, please share an example of icons, the sprite of which breaks without this transformation. Tried to add a valid description of the path of the curve to the test files, but maybe I'm missing something.
And with what tool do you collect the sprite?