Repository: svg/svgo
Pull request #908 (2018-02-19 05:34:15)

Fix issue with prefixIDs plugin not replacing url() refs correctly
When using the prefixIDs plugin  on an SVG with multiple linear gradients, url() values are not replaced correctly because we use `exec` to capture values using the regex. Exec preserves the last matched index, which is undesirable in this case.

Please ref this [ stackoverflow answer ](https://stackoverflow.com/questions/4724701/regexp-exec-returns-null-sporadically) for more information about this.


Patch:
diff --git a/plugins/prefixIds.js b/plugins/prefixIds.js
index ddda078..755baa6 100644
--- a/plugins/prefixIds.js
+++ b/plugins/prefixIds.js
@@ -13,7 +13,7 @@ exports.description = 'prefix IDs';
 
 var path = require('path'),
     csstree = require('css-tree'),
-    cssRx = require('css-url-regex')(),
+    cssRx = require('css-url-regex'),
     unquote = require('unquote'),
     collections = require('./_collections.js'),
     referencesProps = collections.referencesProps,
@@ -37,7 +37,7 @@ var matchId = function(urlVal) {
 
 // Matches an url(...) value, captures the URL
 var matchUrl = function(val) {
-    var urlMatches = cssRx.exec(val);
+    var urlMatches = cssRx().exec(val);
     if (urlMatches === null) {
         return false;
     }


Test patch:
diff --git a/test/plugins/prefixIds.05.svg b/test/plugins/prefixIds.05.svg
new file mode 100644
index 0000000..d7805dd
--- /dev/null
+++ b/test/plugins/prefixIds.05.svg
@@ -0,0 +1,41 @@
+<svg width="340" height="120" xmlns="http://www.w3.org/2000/svg">
+    <defs>
+        <linearGradient id="gradient_1">
+            <stop offset="5%" stop-color="green"/>
+            <stop offset="95%" stop-color="gold"/>
+        </linearGradient>
+        <linearGradient id="gradient_2">
+            <stop offset="5%" stop-color="red"/>
+            <stop offset="95%" stop-color="black"/>
+        </linearGradient>
+        <linearGradient id="gradient_3">
+            <stop offset="5%" stop-color="blue"/>
+            <stop offset="95%" stop-color="orange"/>
+        </linearGradient>
+    </defs>
+    <rect fill="url(#gradient_1)" x="10" y="10" width="100" height="100"/>
+    <rect fill="url(#gradient_2)" x="120" y="10" width="100" height="100"/>
+    <rect fill="url(#gradient_3)" x="230" y="10" width="100" height="100"/>
+</svg>
+
+@@@
+
+<svg width="340" height="120" xmlns="http://www.w3.org/2000/svg">
+    <defs>
+        <linearGradient id="prefixIds_05_svg__gradient_1">
+            <stop offset="5%" stop-color="green"/>
+            <stop offset="95%" stop-color="gold"/>
+        </linearGradient>
+        <linearGradient id="prefixIds_05_svg__gradient_2">
+            <stop offset="5%" stop-color="red"/>
+            <stop offset="95%" stop-color="black"/>
+        </linearGradient>
+        <linearGradient id="prefixIds_05_svg__gradient_3">
+            <stop offset="5%" stop-color="blue"/>
+            <stop offset="95%" stop-color="orange"/>
+        </linearGradient>
+    </defs>
+    <rect fill="url(#prefixIds_05_svg__gradient_1)" x="10" y="10" width="100" height="100"/>
+    <rect fill="url(#prefixIds_05_svg__gradient_2)" x="120" y="10" width="100" height="100"/>
+    <rect fill="url(#prefixIds_05_svg__gradient_3)" x="230" y="10" width="100" height="100"/>
+</svg>