1
0
mirror of https://github.com/svg/svgo.git synced 2025-04-19 10:22:15 +03:00
svgo/plugins/reusePaths.js
Bogdan Chadkin 98c023bdb0
Drop node.class usages (#1533)
We are gonna remove everything outside of xast.
Here's dropped class prop.
2021-08-21 19:42:32 +03:00

86 lines
2.1 KiB
JavaScript

'use strict';
const { traverse } = require('../lib/xast.js');
const JSAPI = require('../lib/svgo/jsAPI');
exports.name = 'reusePaths';
exports.type = 'full';
exports.active = false;
exports.description =
'Finds <path> elements with the same d, fill, and ' +
'stroke, and converts them to <use> elements ' +
'referencing a single <path> def.';
/**
* Finds <path> elements with the same d, fill, and stroke, and converts them to
* <use> elements referencing a single <path> def.
*
* @author Jacob Howcroft
*/
exports.fn = function (root) {
const seen = new Map();
let count = 0;
const defs = [];
traverse(root, (node) => {
if (
node.type !== 'element' ||
node.name !== 'path' ||
node.attributes.d == null
) {
return;
}
const d = node.attributes.d;
const fill = node.attributes.fill || '';
const stroke = node.attributes.stroke || '';
const key = d + ';s:' + stroke + ';f:' + fill;
const hasSeen = seen.get(key);
if (!hasSeen) {
seen.set(key, { elem: node, reused: false });
return;
}
if (!hasSeen.reused) {
hasSeen.reused = true;
if (hasSeen.elem.attributes.id == null) {
hasSeen.elem.attributes.id = 'reuse-' + count++;
}
defs.push(hasSeen.elem);
}
convertToUse(node, hasSeen.elem.attributes.id);
});
if (defs.length > 0) {
const defsTag = new JSAPI(
{
type: 'element',
name: 'defs',
attributes: {},
children: [],
},
root
);
root.children[0].spliceContent(0, 0, defsTag);
for (let def of defs) {
const defClone = def.clone();
delete defClone.attributes.transform;
defsTag.spliceContent(0, 0, defClone);
// Convert the original def to a use so the first usage isn't duplicated.
def = convertToUse(def, defClone.attributes.id);
delete def.attributes.id;
}
}
return root;
};
/** */
function convertToUse(item, href) {
item.renameElem('use');
delete item.attributes.d;
delete item.attributes.stroke;
delete item.attributes.fill;
item.attributes['xlink:href'] = '#' + href;
delete item.pathJS;
return item;
}