svg/svgo

[cleanupIDs] symbol is incorrectly removed when its ID is *NOT* used by URL-encoded reference

liuweifeng opened this issue · 0 comments

Describe the bug

Last year's PR #1880 fixed the issue with URL encoding of IDs in href or url(). However, in practical use, we found that due to differences in SVG export tools or improper use, the SVG files delivered by designers to developers often have references to graphics, gradients, etc., in url() that are not necessarily URL-encoded.

Here is one of my actual examples (with business desensitization):

<svg xmlns="http://www.w3.org/2000/svg">
  <defs>
    <linearGradient id="渐变_1" x1="0%" y1="0%" x2="100%" y2="0%">
      <stop offset="10%" stop-color="#c71700" />
      <stop offset="60%" stop-color="orange" />
      <stop offset="100%" stop-color="#5a2100" />
    </linearGradient>
  </defs>
  <rect x="30" y="30" height="150" width="370" fill="url(#渐变_1)" />
</svg>

After this SVG was processed by svgo, it became like this:

<svg xmlns="http://www.w3.org/2000/svg">
  <path fill="url(#渐变_1)" d="M30 30h370v150H30z"/>
</svg>

I traced the code and found that during the search for reference IDs, only URL-encoded IDs were used, which led to the unencoded IDs not being matched. As a result, in subsequent processing, they were considered as unreferenced, useless nodes and were deleted.

`#${encodeURI(id)}`,

I will submit a PR shortly to fix this issue.

Desktop (please complete the following information):

  • SVGO Version 3.2.0
  • NodeJs Version 20.12.0
  • OS: macOS