From 86880fb1a257b0f2ff1a6a915782d583d17bae48 Mon Sep 17 00:00:00 2001 From: Seth Falco Date: Tue, 19 Sep 2023 22:31:26 +0100 Subject: [PATCH] fix: reuse defs tag in reusePaths --- plugins/reusePaths.js | 52 +++++++++++++++++++++++++--------- test/plugins/reusePaths.04.svg | 23 +++++++++++++++ 2 files changed, 62 insertions(+), 13 deletions(-) create mode 100644 test/plugins/reusePaths.04.svg diff --git a/plugins/reusePaths.js b/plugins/reusePaths.js index 4d91d6f9d..d0cce6d9e 100644 --- a/plugins/reusePaths.js +++ b/plugins/reusePaths.js @@ -26,9 +26,18 @@ exports.fn = () => { */ const paths = new Map(); + /** + * Reference to the first defs element that is a direct child of the svg + * element if one exists. + * + * @type {XastElement} + * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs + */ + let svgDefs; + return { element: { - enter: (node) => { + enter: (node, parentNode) => { if (node.name === 'path' && node.attributes.d != null) { const d = node.attributes.d; const fill = node.attributes.fill || ''; @@ -41,6 +50,15 @@ exports.fn = () => { } list.push(node); } + + if ( + svgDefs == null && + node.name === 'defs' && + parentNode.type === 'element' && + parentNode.name === 'svg' + ) { + svgDefs = node; + } }, exit: (node, parentNode) => { @@ -48,17 +66,22 @@ exports.fn = () => { /** * @type {XastElement} */ - const defsTag = { - type: 'element', - name: 'defs', - attributes: {}, - children: [], - }; - // TODO remove legacy parentNode in v4 - Object.defineProperty(defsTag, 'parentNode', { - writable: true, - value: node, - }); + let defsTag = svgDefs; + + if (defsTag == null) { + defsTag = { + type: 'element', + name: 'defs', + attributes: {}, + children: [], + }; + // TODO remove legacy parentNode in v4 + Object.defineProperty(defsTag, 'parentNode', { + writable: true, + value: node, + }); + } + let index = 0; for (const list of paths.values()) { if (list.length > 1) { @@ -102,7 +125,10 @@ exports.fn = () => { if (node.attributes['xmlns:xlink'] == null) { node.attributes['xmlns:xlink'] = 'http://www.w3.org/1999/xlink'; } - node.children.unshift(defsTag); + + if (svgDefs == null) { + node.children.unshift(defsTag); + } } } }, diff --git a/test/plugins/reusePaths.04.svg b/test/plugins/reusePaths.04.svg new file mode 100644 index 000000000..5d5b57425 --- /dev/null +++ b/test/plugins/reusePaths.04.svg @@ -0,0 +1,23 @@ +Don't create a new defs tag if one already exists as a direct child of the svg +element. + +=== + + + + + + + + +@@@ + + + + + + + + +