svgo icon indicating copy to clipboard operation
svgo copied to clipboard

Convert <use> tags. By default only defs with a single <use>.

Open nikparo opened this issue 7 years ago • 5 comments

I ran into exported svg's that use a lot of unnecessary defs, and decided to take matters into my own hands...

This plugin:

  • loops through the svg to first find all <defs> element definitions. It then finds all <use> items. (In hindsight, this should have been done in a single loop.)
  • Filters out the element definitions that are only used once (by default, but optional)
  • Converts <use> to <g> and inserts a clone of the definition.
  • Removes the definitions that have been inlined.

This plugin does not remove unused definitions or collapse the resulting groups, leaving that for removeUselessDefs and collapseGroups.

I believe this plugin would cover the request in https://github.com/svg/svgo/issues/563

[edit: now removes the definitions that have been inlined]

nikparo avatar Feb 26 '17 15:02 nikparo

~~May have created the request a bit too early, noticed that there are some problems with at least masks and clip paths.~~

[Edit: My test was faulty.]

nikparo avatar Feb 26 '17 16:02 nikparo

There are several caveats in your code.

GreLI avatar Mar 11 '17 13:03 GreLI

I don't think this PR handles CSS cascades correctly. According to the SVG spec, CSS cascade is applied to the referenced elements, not the (conceptually) cloned elements that make up the shadow DOM. What I think you would have to do is:

  1. Run some sort of inlineStyles plugin (i.e. #592) on the SVG so that all of the elements that are descendants of a <defs> element are assigned their styled attributes.
  2. Then run this plugin (i.e. find the <use> tags and replace them with the deeply cloned elements).
  3. Make sure that any property-inheritance-related plugins are run after step (2).

Also I would take a look at the SVG spec on the <use> and <defs> tags since I also saw some things that were missing. For example, the plugin doesn't handle cases where x, y, width, and/or height attributes are specified on the <use> tag, etc.

Also this plugin doesn't handle the case where the <use> tag references another <use> tag, which apparently is possible.

alexjlockwood avatar Mar 12 '17 00:03 alexjlockwood

Well, SVGO doesn't handle CSS almost at all.

GreLI avatar Mar 12 '17 09:03 GreLI

A window.getComputedStyle() implementation would be useful here. It is quite similar to inlineStyles plugin and style related API, an extra lookup table or property would be required because it would be too slow otherwise. This could be implemented as extra methods in css-tools when style support has been merged in.

strarsis avatar Mar 24 '17 16:03 strarsis