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

Fix ID replacements not being performed in style elements #59

Open fortinmike opened 2 years ago

fortinmike commented 2 years ago

Problem

svg-inject does not add suffixes to IDs located in style elements; it only replaces url(#id) references. This breaks styles and animations such as those exported by SVGator due to "standalone" IDs not being suffixed, when the makeIdsUnique option is enabled.

Fix

Replace the regex for id replacements in the style element with a more generalized one that matches #id as well as url(#id) (as before).

Although this is a much more generalized regex, as far as I know this shouldn't cause issues with fancy CSS syntax.

Example

Original SVG

<style>
    <![CDATA[#emVKjsoi9OL2 {animation: emVKjsoi9OL2_c_o 8000ms linear 1 normal forwards}@keyframes emVKjsoi9OL2_c_o { 0% {opacity: 0} 2.5% {opacity: 1} 100% {opacity: 1}} #emVKjsoi9OL3 {animation: emVKjsoi9OL3_c_o 8000ms linear 1 normal forwards}@keyframes emVKjsoi9OL3_c_o { 0% {opacity: 0} 83.75% {opacity: 0} 86.25% {opacity: 1} 100% {opacity: 1}} #emVKjsoi9OL4 {animation: emVKjsoi9OL4_s_do 8000ms linear 1 normal forwards}@keyframes emVKjsoi9OL4_s_do { 0% {stroke-dashoffset: 500} 2.5% {stroke-dashoffset: 500} 99.875% {stroke-dashoffset: 50} 100% {stroke-dashoffset: 50}}]]>
</style>

After injection with unfixed svg-inject

Styles stay exactly the same after injection, disconnecting styles from the now-suffixed elements in the SVG body.

After injection with this pull request

<style>
    <![CDATA[#emVKjsoi9OL2--inject-1 {animation: emVKjsoi9OL2_c_o 8000ms linear 1 normal forwards}@keyframes emVKjsoi9OL2_c_o { 0% {opacity: 0} 2.5% {opacity: 1} 100% {opacity: 1}} #emVKjsoi9OL3--inject-1 {animation: emVKjsoi9OL3_c_o 8000ms linear 1 normal forwards}@keyframes emVKjsoi9OL3_c_o { 0% {opacity: 0} 83.75% {opacity: 0} 86.25% {opacity: 1} 100% {opacity: 1}} #emVKjsoi9OL4--inject-1 {animation: emVKjsoi9OL4_s_do 8000ms linear 1 normal forwards}@keyframes emVKjsoi9OL4_s_do { 0% {stroke-dashoffset: 500} 2.5% {stroke-dashoffset: 500} 99.875% {stroke-dashoffset: 50} 100% {stroke-dashoffset: 50}}]]>
</style>
fortinmike commented 2 years ago

Oh and by the way I also added a .nvmrc file because the svg-inject gulp task fails on recent node.js versions. I hope that's OK. I did not do further tests to see which maximum version of node.js svg-inject works with, but node.js 10.5.0 is fine. Feel free to change that to a more appropriate version.

beaulieufrancois commented 2 years ago

Great! Works on my app.