first
This commit is contained in:
113
node_modules/svgo/plugins/sortAttrs.js
generated
vendored
Normal file
113
node_modules/svgo/plugins/sortAttrs.js
generated
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
'use strict';
|
||||
|
||||
exports.type = 'visitor';
|
||||
exports.name = 'sortAttrs';
|
||||
exports.active = false;
|
||||
exports.description = 'Sort element attributes for better compression';
|
||||
|
||||
/**
|
||||
* Sort element attributes for better compression
|
||||
*
|
||||
* @author Nikolay Frantsev
|
||||
*
|
||||
* @type {import('../lib/types').Plugin<{
|
||||
* order?: Array<string>
|
||||
* xmlnsOrder?: 'front' | 'alphabetical'
|
||||
* }>}
|
||||
*/
|
||||
exports.fn = (_root, params) => {
|
||||
const {
|
||||
order = [
|
||||
'id',
|
||||
'width',
|
||||
'height',
|
||||
'x',
|
||||
'x1',
|
||||
'x2',
|
||||
'y',
|
||||
'y1',
|
||||
'y2',
|
||||
'cx',
|
||||
'cy',
|
||||
'r',
|
||||
'fill',
|
||||
'stroke',
|
||||
'marker',
|
||||
'd',
|
||||
'points',
|
||||
],
|
||||
xmlnsOrder = 'front',
|
||||
} = params;
|
||||
|
||||
/**
|
||||
* @type {(name: string) => number}
|
||||
*/
|
||||
const getNsPriority = (name) => {
|
||||
if (xmlnsOrder === 'front') {
|
||||
// put xmlns first
|
||||
if (name === 'xmlns') {
|
||||
return 3;
|
||||
}
|
||||
// xmlns:* attributes second
|
||||
if (name.startsWith('xmlns:')) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
// other namespaces after and sort them alphabetically
|
||||
if (name.includes(':')) {
|
||||
return 1;
|
||||
}
|
||||
// other attributes
|
||||
return 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {(a: [string, string], b: [string, string]) => number}
|
||||
*/
|
||||
const compareAttrs = ([aName], [bName]) => {
|
||||
// sort namespaces
|
||||
const aPriority = getNsPriority(aName);
|
||||
const bPriority = getNsPriority(bName);
|
||||
const priorityNs = bPriority - aPriority;
|
||||
if (priorityNs !== 0) {
|
||||
return priorityNs;
|
||||
}
|
||||
// extract the first part from attributes
|
||||
// for example "fill" from "fill" and "fill-opacity"
|
||||
const [aPart] = aName.split('-');
|
||||
const [bPart] = bName.split('-');
|
||||
// rely on alphabetical sort when the first part is the same
|
||||
if (aPart !== bPart) {
|
||||
const aInOrderFlag = order.includes(aPart) ? 1 : 0;
|
||||
const bInOrderFlag = order.includes(bPart) ? 1 : 0;
|
||||
// sort by position in order param
|
||||
if (aInOrderFlag === 1 && bInOrderFlag === 1) {
|
||||
return order.indexOf(aPart) - order.indexOf(bPart);
|
||||
}
|
||||
// put attributes from order param before others
|
||||
const priorityOrder = bInOrderFlag - aInOrderFlag;
|
||||
if (priorityOrder !== 0) {
|
||||
return priorityOrder;
|
||||
}
|
||||
}
|
||||
// sort alphabetically
|
||||
return aName < bName ? -1 : 1;
|
||||
};
|
||||
|
||||
return {
|
||||
element: {
|
||||
enter: (node) => {
|
||||
const attrs = Object.entries(node.attributes);
|
||||
attrs.sort(compareAttrs);
|
||||
/**
|
||||
* @type {Record<string, string>}
|
||||
*/
|
||||
const sortedAttributes = {};
|
||||
for (const [name, value] of attrs) {
|
||||
sortedAttributes[name] = value;
|
||||
}
|
||||
node.attributes = sortedAttributes;
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
Reference in New Issue
Block a user