Repository: svg/svgo
Pull request #565 (2016-07-06 19:58:05)

Add `removeElements` plugin
This is a simple plugin that allows you to remove certain elements based on their `id` attributes.

We need this for a specific workflow in one of our projects where SVGs are exported from Photoshop with a `rect` to set the specifically to set the `viewBox` dimensions—but that `rect` needs to be removed before the SVGs are rendered in our app.

Definitely open to thoughts and improvements!


Patch:
diff --git a/plugins/removeElementsByAttr.js b/plugins/removeElementsByAttr.js
new file mode 100644
index 0000000..c726f70
--- /dev/null
+++ b/plugins/removeElementsByAttr.js
@@ -0,0 +1,80 @@
+'use strict';
+
+exports.type = 'perItem';
+
+exports.active = false;
+
+exports.description = 'removes arbitrary elements by ID or className (disabled by default)';
+
+exports.params = {
+    id: [],
+    class: []
+};
+
+/**
+ * Remove arbitrary SVG elements by ID or className.
+ *
+ * @param id
+ *   examples:
+ *
+ *     > single: remove element with ID of `elementID`
+ *     ---
+ *     removeElementsByAttr:
+ *       id: 'elementID'
+ *
+ *     > list: remove multiple elements by ID
+ *     ---
+ *     removeElementsByAttr:
+ *       id:
+ *         - 'elementID'
+ *         - 'anotherID'
+ *
+ * @param class
+ *   examples:
+ *
+ *     > single: remove all elements with class of `elementClass`
+ *     ---
+ *     removeElementsByAttr:
+ *       class: 'elementClass'
+ *
+ *     > list: remove all elements with class of `elementClass` or `anotherClass`
+ *     ---
+ *     removeElementsByAttr:
+ *       class:
+ *         - 'elementClass'
+ *         - 'anotherClass'
+ *
+ * @param {Object} item current iteration item
+ * @param {Object} params plugin params
+ * @return {Boolean} if false, item will be filtered out
+ *
+ * @author Eli Dupuis (@elidupuis)
+ */
+exports.fn = function(item, params) {
+    var elemId, elemClass;
+
+    // wrap params in an array if not already
+    ['id', 'class'].forEach(function(key) {
+        if (!Array.isArray(params[key])) {
+            params[key] = [ params[key] ];
+        }
+    });
+
+    // abort if current item is no an element
+    if (!item.isElem()) {
+        return;
+    }
+
+    // remove element if it's `id` matches configured `id` params
+    elemId = item.attr('id');
+    if (elemId) {
+        return params.id.indexOf(elemId.value) === -1;
+    }
+
+    // remove element if it's `class` contains any of the configured `class` params
+    elemClass = item.attr('class');
+    if (elemClass) {
+        var hasClassRegex = new RegExp(params.class.join('|'));
+        return !hasClassRegex.test(elemClass.value);
+    }
+};


Test patch:
diff --git a/test/plugins/removeElementsByAttr.01.svg b/test/plugins/removeElementsByAttr.01.svg
new file mode 100644
index 0000000..9757a69
--- /dev/null
+++ b/test/plugins/removeElementsByAttr.01.svg
@@ -0,0 +1,11 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect id="someID" width="19" height="19"/>
+    <path id="close" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+</svg>
+
+@@@
+
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect id="someID" width="19" height="19"/>
+    <path id="close" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+</svg>
diff --git a/test/plugins/removeElementsByAttr.02.svg b/test/plugins/removeElementsByAttr.02.svg
new file mode 100644
index 0000000..966f4aa
--- /dev/null
+++ b/test/plugins/removeElementsByAttr.02.svg
@@ -0,0 +1,14 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect id="someID" width="19" height="19"/>
+    <path id="close" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+</svg>
+
+@@@
+
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <path id="close" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+</svg>
+
+@@@
+
+{ "id": "someID" }
diff --git a/test/plugins/removeElementsByAttr.03.svg b/test/plugins/removeElementsByAttr.03.svg
new file mode 100644
index 0000000..aa15fc9
--- /dev/null
+++ b/test/plugins/removeElementsByAttr.03.svg
@@ -0,0 +1,12 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect id="someID" width="19" height="19"/>
+    <path id="anotherID" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+</svg>
+
+@@@
+
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19"/>
+
+@@@
+
+{ "id": ["someID", "anotherID"] }
diff --git a/test/plugins/removeElementsByAttr.04.svg b/test/plugins/removeElementsByAttr.04.svg
new file mode 100644
index 0000000..ba9ce20
--- /dev/null
+++ b/test/plugins/removeElementsByAttr.04.svg
@@ -0,0 +1,17 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect class="someClass" width="19" height="19"/>
+    <path class="close" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+    <rect class="someClass extraClass"/>
+    <rect class="SOMEclass case-sensitive"/>
+</svg>
+
+@@@
+
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <path class="close" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+    <rect class="SOMEclass case-sensitive"/>
+</svg>
+
+@@@
+
+{ "class": "someClass" }
diff --git a/test/plugins/removeElementsByAttr.05.svg b/test/plugins/removeElementsByAttr.05.svg
new file mode 100644
index 0000000..1fb474a
--- /dev/null
+++ b/test/plugins/removeElementsByAttr.05.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect class="someClass" width="19" height="19"/>
+    <path class="anotherClass" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+    <rect class="someClass extraClass"/>
+</svg>
+
+@@@
+
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19"/>
+
+@@@
+
+{ "class": ["someClass", "anotherClass"] }
diff --git a/test/plugins/removeElementsByAttr.06.svg b/test/plugins/removeElementsByAttr.06.svg
new file mode 100644
index 0000000..f5fd291
--- /dev/null
+++ b/test/plugins/removeElementsByAttr.06.svg
@@ -0,0 +1,16 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect class="someClass" width="19" height="19"/>
+    <path class="someClass extraClass" d="M1093.5,31.792l-0.72.721-8.27-8.286-8.28,8.286-0.72-.721,8.28-8.286-8.28-8.286,0.72-.721,8.28,8.286,8.27-8.286,0.72,0.721-8.27,8.286Z" transform="translate(-1075 -14)"/>
+    <rect class="anotherClass"/>
+    <path id="someID" class="anotherID"/>
+</svg>
+
+@@@
+
+<svg xmlns="http://www.w3.org/2000/svg" width="19" height="19" viewBox="0 0 19 19">
+    <rect class="anotherClass"/>
+</svg>
+
+@@@
+
+{ "id": "someID", "class": "someClass" }