1
0
mirror of https://github.com/svg/svgo.git synced 2025-07-31 07:44:22 +03:00

Add config to preserve IDs based on prefix matching (#1060)

add parameter to preserve IDs based on prefix matching
This commit is contained in:
Brad Kotsopoulos
2019-02-24 13:02:03 -05:00
committed by Lev Solntsev
parent dcd95d50ff
commit 7eeb5d064d
5 changed files with 113 additions and 3 deletions

View File

@ -11,6 +11,7 @@ exports.params = {
minify: true, minify: true,
prefix: '', prefix: '',
preserve: [], preserve: [],
preservePrefixes: [],
force: false force: false
}; };
@ -41,6 +42,7 @@ exports.fn = function(data, params) {
referencesIDs = new Map(), referencesIDs = new Map(),
hasStyleOrScript = false, hasStyleOrScript = false,
preserveIDs = new Set(Array.isArray(params.preserve) ? params.preserve : params.preserve ? [params.preserve] : []), preserveIDs = new Set(Array.isArray(params.preserve) ? params.preserve : params.preserve ? [params.preserve] : []),
preserveIDPrefixes = new Set(Array.isArray(params.preservePrefixes) ? params.preservePrefixes : (params.preservePrefixes ? [params.preservePrefixes] : [])),
idValuePrefix = '#', idValuePrefix = '#',
idValuePostfix = '.'; idValuePostfix = '.';
@ -54,7 +56,7 @@ exports.fn = function(data, params) {
for (var i = 0; i < items.content.length && !hasStyleOrScript; i++) { for (var i = 0; i < items.content.length && !hasStyleOrScript; i++) {
var item = items.content[i]; var item = items.content[i];
// quit if <style> of <script> presents ('force' param prevents quitting) // quit if <style> or <script> present ('force' param prevents quitting)
if (!params.force) { if (!params.force) {
if (item.isElem(styleOrScript)) { if (item.isElem(styleOrScript)) {
hasStyleOrScript = true; hasStyleOrScript = true;
@ -124,7 +126,7 @@ exports.fn = function(data, params) {
if (IDs.has(key)) { if (IDs.has(key)) {
// replace referenced IDs with the minified ones // replace referenced IDs with the minified ones
if (params.minify && !preserveIDs.has(key)) { if (params.minify && !preserveIDs.has(key) && !idMatchesPrefix(preserveIDPrefixes, key)) {
currentIDstring = getIDstring(currentID = generateID(currentID), params); currentIDstring = getIDstring(currentID = generateID(currentID), params);
IDs.get(key).attr('id').value = currentIDstring; IDs.get(key).attr('id').value = currentIDstring;
@ -141,7 +143,7 @@ exports.fn = function(data, params) {
// remove non-referenced IDs attributes from elements // remove non-referenced IDs attributes from elements
if (params.remove) { if (params.remove) {
for(var keyElem of IDs) { for(var keyElem of IDs) {
if (!preserveIDs.has(keyElem[0])) { if (!preserveIDs.has(keyElem[0]) && !idMatchesPrefix(preserveIDPrefixes, keyElem[0])) {
keyElem[1].removeAttr('id'); keyElem[1].removeAttr('id');
} }
} }
@ -149,6 +151,20 @@ exports.fn = function(data, params) {
return data; return data;
}; };
/**
* Check if an ID starts with any one of a list of strings.
*
* @param {Array} of prefix strings
* @param {String} current ID
* @return {Boolean} if currentID starts with one of the strings in prefixArray
*/
function idMatchesPrefix(prefixArray, currentID) {
if (!currentID) return false;
for (var prefix of prefixArray) if (currentID.startsWith(prefix)) return true;
return false;
}
/** /**
* Generate unique minimal ID. * Generate unique minimal ID.
* *

View File

@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 230 120">
<circle id="garbage1" fill="red" cx="60" cy="60" r="50"/>
<rect id="garbage2" fill="blue" x="120" y="10" width="100" height="100"/>
<view id="xyzgarbage1" viewBox="0 0 120 120"/>
<view id="xyzgarbage2" viewBox="110 0 120 120"/>
</svg>
@@@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 230 120">
<circle fill="red" cx="60" cy="60" r="50"/>
<rect fill="blue" x="120" y="10" width="100" height="100"/>
<view id="xyzgarbage1" viewBox="0 0 120 120"/>
<view id="xyzgarbage2" viewBox="110 0 120 120"/>
</svg>
@@@
{"preservePrefixes": ["xyz"]}

After

Width:  |  Height:  |  Size: 728 B

View File

@ -0,0 +1,22 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 120 120">
<style>
svg .hidden { display: none; }
svg .hidden:target { display: inline; }
</style>
<circle id="pre1_circle" class="hidden" fill="red" cx="60" cy="60" r="50"/>
<rect id="pre2_rect" class="hidden" fill="blue" x="10" y="10" width="100" height="100"/>
</svg>
@@@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 120 120">
<style>
svg .hidden { display: none; } svg .hidden:target { display: inline; }
</style>
<circle id="pre1_circle" class="hidden" fill="red" cx="60" cy="60" r="50"/>
<rect id="pre2_rect" class="hidden" fill="blue" x="10" y="10" width="100" height="100"/>
</svg>
@@@
{"force": true, "preservePrefixes": ["pre1_", "pre2_"]}

After

Width:  |  Height:  |  Size: 856 B

View File

@ -0,0 +1,34 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 120 120">
<style>
svg .hidden { display: none; }
svg .hidden:target { display: inline; }
</style>
<defs>
<circle id="circle" fill="red" cx="60" cy="60" r="50"/>
<rect id="rect" fill="blue" x="10" y="10" width="100" height="100"/>
</defs>
<g id="pre1_figure" class="hidden">
<use xlink:href="#circle"/>
<use href="#rect"/>
</g>
</svg>
@@@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 120 120">
<style>
svg .hidden { display: none; } svg .hidden:target { display: inline; }
</style>
<defs>
<circle id="a" fill="red" cx="60" cy="60" r="50"/>
<rect id="b" fill="blue" x="10" y="10" width="100" height="100"/>
</defs>
<g id="pre1_figure" class="hidden">
<use xlink:href="#a"/>
<use href="#b"/>
</g>
</svg>
@@@
{"force": true, "preservePrefixes": "pre1_"}

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 230 120">
<circle id="circle" fill="red" cx="60" cy="60" r="50"/>
<rect id="rect" fill="blue" x="120" y="10" width="100" height="100"/>
<view id="circle-suffix" viewBox="0 0 120 120"/>
<view id="rect-suffix" viewBox="110 0 120 120"/>
</svg>
@@@
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 230 120">
<circle id="circle" fill="red" cx="60" cy="60" r="50"/>
<rect id="rect" fill="blue" x="120" y="10" width="100" height="100"/>
<view viewBox="0 0 120 120"/>
<view id="rect-suffix" viewBox="110 0 120 120"/>
</svg>
@@@
{"preserve": ["circle"], "preservePrefixes": ["suffix", "rect"]}

After

Width:  |  Height:  |  Size: 764 B