iconfu / svg-inject

A tiny, intuitive, robust, caching solution for injecting SVG files inline into the DOM.
MIT License
800 stars 85 forks source link

IDs not replaced in <style> elements #20

Closed waruyama closed 6 years ago

waruyama commented 6 years ago

Some graphics programs like Corel Draw export SVGs with the style embedded into a CDATA section inside a style element. Currently IDs inside style elements are not converted.

Here is an example SVG:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1024px" height="1024px" version="1.1" style="shape-rendering:geometricPrecision; text-rendering:geometricPrecision; image-rendering:optimizeQuality; fill-rule:evenodd; clip-rule:evenodd"
viewBox="0 0 102400 102400"
 xmlns:xlink="http://www.w3.org/1999/xlink">
 <defs>
  <style type="text/css">
   <![CDATA[
    .fil0 {fill:url(#id0)}
   ]]>
  </style>
  <linearGradient id="id0" gradientUnits="userSpaceOnUse" x1="30009.4" y1="28336" x2="72690.6" y2="59764">
   <stop offset="0" style="stop-color:#1E87E3"/>
   <stop offset="1" style="stop-color:#E33834"/>
  </linearGradient>
 </defs>
 <g id="Ebene_x0020_1">
  <ellipse class="fil0" cx="51350" cy="44050" rx="31400" ry="31850"/>
 </g>
</svg>
waruyama commented 6 years ago

A style element can contain the style data either as plain text or as a CDATA section. An approach that works cross-browser can look like this:

  var funcIriRegExp = new RegExp('url\\("?#([a-zA-Z][\\w:.-]*)"?\\)', 'g');
  ...   
  if (element.tagName == 'style') {
    element.textContent = element.textContent.replace(funcIriRegExp, 'url(#$1' + idSuffix + ')');
  }

Note that we are using textContent instead of innerHTML, because the latter does not work on Internet Explorer.

waruyama commented 6 years ago

Fixed in a809111