1
0
mirror of https://github.com/svg/svgo.git synced 2025-07-29 20:21:14 +03:00

Format all plugins with prettier

This commit is contained in:
Bogdan Chadkin
2021-03-09 19:58:00 +03:00
parent 1be0d0dba1
commit 00ec0f71fe
41 changed files with 2053 additions and 1992 deletions

View File

@ -7,24 +7,74 @@ exports.active = true;
exports.description = 'removes unused IDs and minifies used';
exports.params = {
remove: true,
minify: true,
prefix: '',
preserve: [],
preservePrefixes: [],
force: false
remove: true,
minify: true,
prefix: '',
preserve: [],
preservePrefixes: [],
force: false,
};
var referencesProps = new Set(require('./_collections').referencesProps),
regReferencesUrl = /\burl\(("|')?#(.+?)\1\)/,
regReferencesHref = /^#(.+?)$/,
regReferencesBegin = /(\w+)\./,
styleOrScript = ['style', 'script'],
generateIDchars = [
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
],
maxIDindex = generateIDchars.length - 1;
regReferencesUrl = /\burl\(("|')?#(.+?)\1\)/,
regReferencesHref = /^#(.+?)$/,
regReferencesBegin = /(\w+)\./,
styleOrScript = ['style', 'script'],
generateIDchars = [
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
],
maxIDindex = generateIDchars.length - 1;
/**
* Remove unused and minify used IDs
@ -35,128 +85,155 @@ var referencesProps = new Set(require('./_collections').referencesProps),
*
* @author Kir Belevich
*/
exports.fn = function(data, params) {
var currentID,
currentIDstring,
IDs = new Map(),
referencesIDs = new Map(),
hasStyleOrScript = false,
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 = '#',
idValuePostfix = '.';
exports.fn = function (data, params) {
var currentID,
currentIDstring,
IDs = new Map(),
referencesIDs = new Map(),
hasStyleOrScript = false,
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 = '#',
idValuePostfix = '.';
/**
* Bananas!
*
* @param {Array} items input items
* @return {Array} output items
*/
function monkeys(items) {
for (var i = 0; i < items.content.length && !hasStyleOrScript; i++) {
var item = items.content[i];
/**
* Bananas!
*
* @param {Array} items input items
* @return {Array} output items
*/
function monkeys(items) {
for (var i = 0; i < items.content.length && !hasStyleOrScript; i++) {
var item = items.content[i];
// quit if <style> or <script> present ('force' param prevents quitting)
if (!params.force) {
var isNotEmpty = Boolean(item.content);
if (item.isElem(styleOrScript) && isNotEmpty) {
hasStyleOrScript = true;
continue;
}
// Don't remove IDs if the whole SVG consists only of defs.
if (item.isElem('svg') && item.content) {
var hasDefsOnly = true;
for (var j = 0; j < item.content.length; j++) {
if (!item.content[j].isElem('defs')) {
hasDefsOnly = false;
break;
}
}
if (hasDefsOnly) {
break;
}
}
}
// …and don't remove any ID if yes
if (item.isElem()) {
item.eachAttr(function(attr) {
var key, match;
// save IDs
if (attr.name === 'id') {
key = attr.value;
if (IDs.has(key)) {
item.removeAttr('id'); // remove repeated id
} else {
IDs.set(key, item);
}
return;
}
// save references
if (referencesProps.has(attr.name) && (match = attr.value.match(regReferencesUrl))) {
key = match[2]; // url() reference
} else if (
attr.local === 'href' && (match = attr.value.match(regReferencesHref)) ||
attr.name === 'begin' && (match = attr.value.match(regReferencesBegin))
) {
key = match[1]; // href reference
}
if (key) {
var ref = referencesIDs.get(key) || [];
ref.push(attr);
referencesIDs.set(key, ref);
}
});
}
// go deeper
if (item.content) {
monkeys(item);
}
// quit if <style> or <script> present ('force' param prevents quitting)
if (!params.force) {
var isNotEmpty = Boolean(item.content);
if (item.isElem(styleOrScript) && isNotEmpty) {
hasStyleOrScript = true;
continue;
}
return items;
}
data = monkeys(data);
// Don't remove IDs if the whole SVG consists only of defs.
if (item.isElem('svg') && item.content) {
var hasDefsOnly = true;
if (hasStyleOrScript) {
return data;
}
const idPreserved = id => preserveIDs.has(id) || idMatchesPrefix(preserveIDPrefixes, id);
for (var ref of referencesIDs) {
var key = ref[0];
if (IDs.has(key)) {
// replace referenced IDs with the minified ones
if (params.minify && !idPreserved(key)) {
do {
currentIDstring = getIDstring(currentID = generateID(currentID), params);
} while (idPreserved(currentIDstring));
IDs.get(key).attr('id').value = currentIDstring;
for (var attr of ref[1]) {
attr.value = attr.value.includes(idValuePrefix) ?
attr.value.replace(idValuePrefix + key, idValuePrefix + currentIDstring) :
attr.value.replace(key + idValuePostfix, currentIDstring + idValuePostfix);
}
for (var j = 0; j < item.content.length; j++) {
if (!item.content[j].isElem('defs')) {
hasDefsOnly = false;
break;
}
// don't remove referenced IDs
IDs.delete(key);
}
if (hasDefsOnly) {
break;
}
}
}
// remove non-referenced IDs attributes from elements
if (params.remove) {
for(var keyElem of IDs) {
if (!idPreserved(keyElem[0])) {
keyElem[1].removeAttr('id');
}
// …and don't remove any ID if yes
if (item.isElem()) {
item.eachAttr(function (attr) {
var key, match;
// save IDs
if (attr.name === 'id') {
key = attr.value;
if (IDs.has(key)) {
item.removeAttr('id'); // remove repeated id
} else {
IDs.set(key, item);
}
}
return;
}
// save references
if (
referencesProps.has(attr.name) &&
(match = attr.value.match(regReferencesUrl))
) {
key = match[2]; // url() reference
} else if (
(attr.local === 'href' &&
(match = attr.value.match(regReferencesHref))) ||
(attr.name === 'begin' &&
(match = attr.value.match(regReferencesBegin)))
) {
key = match[1]; // href reference
}
if (key) {
var ref = referencesIDs.get(key) || [];
ref.push(attr);
referencesIDs.set(key, ref);
}
});
}
// go deeper
if (item.content) {
monkeys(item);
}
}
return items;
}
data = monkeys(data);
if (hasStyleOrScript) {
return data;
}
const idPreserved = (id) =>
preserveIDs.has(id) || idMatchesPrefix(preserveIDPrefixes, id);
for (var ref of referencesIDs) {
var key = ref[0];
if (IDs.has(key)) {
// replace referenced IDs with the minified ones
if (params.minify && !idPreserved(key)) {
do {
currentIDstring = getIDstring(
(currentID = generateID(currentID)),
params
);
} while (idPreserved(currentIDstring));
IDs.get(key).attr('id').value = currentIDstring;
for (var attr of ref[1]) {
attr.value = attr.value.includes(idValuePrefix)
? attr.value.replace(
idValuePrefix + key,
idValuePrefix + currentIDstring
)
: attr.value.replace(
key + idValuePostfix,
currentIDstring + idValuePostfix
);
}
}
// don't remove referenced IDs
IDs.delete(key);
}
}
// remove non-referenced IDs attributes from elements
if (params.remove) {
for (var keyElem of IDs) {
if (!idPreserved(keyElem[0])) {
keyElem[1].removeAttr('id');
}
}
}
return data;
};
/**
@ -167,10 +244,10 @@ exports.fn = function(data, params) {
* @return {Boolean} if currentID starts with one of the strings in prefixArray
*/
function idMatchesPrefix(prefixArray, currentID) {
if (!currentID) return false;
if (!currentID) return false;
for (var prefix of prefixArray) if (currentID.startsWith(prefix)) return true;
return false;
for (var prefix of prefixArray) if (currentID.startsWith(prefix)) return true;
return false;
}
/**
@ -180,24 +257,24 @@ function idMatchesPrefix(prefixArray, currentID) {
* @return {Array} generated ID array
*/
function generateID(currentID) {
if (!currentID) return [0];
if (!currentID) return [0];
currentID[currentID.length - 1]++;
currentID[currentID.length - 1]++;
for(var i = currentID.length - 1; i > 0; i--) {
if (currentID[i] > maxIDindex) {
currentID[i] = 0;
for (var i = currentID.length - 1; i > 0; i--) {
if (currentID[i] > maxIDindex) {
currentID[i] = 0;
if (currentID[i - 1] !== undefined) {
currentID[i - 1]++;
}
}
if (currentID[i - 1] !== undefined) {
currentID[i - 1]++;
}
}
if (currentID[0] > maxIDindex) {
currentID[0] = 0;
currentID.unshift(0);
}
return currentID;
}
if (currentID[0] > maxIDindex) {
currentID[0] = 0;
currentID.unshift(0);
}
return currentID;
}
/**
@ -207,6 +284,6 @@ function generateID(currentID) {
* @return {String} output ID string
*/
function getIDstring(arr, params) {
var str = params.prefix;
return str + arr.map(i => generateIDchars[i]).join('');
var str = params.prefix;
return str + arr.map((i) => generateIDchars[i]).join('');
}