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:
@ -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('');
|
||||
}
|
||||
|
Reference in New Issue
Block a user