From 0c6f7980ae237b82324c4536c206426020c910f3 Mon Sep 17 00:00:00 2001 From: Seth Falco Date: Mon, 18 Sep 2023 20:31:04 +0100 Subject: [PATCH] fix(reusePaths): dont reuse id if referenced in href --- plugins/reusePaths.js | 21 +++++++++++++++++- test/plugins/reusePaths.04.svg | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/plugins/reusePaths.04.svg diff --git a/plugins/reusePaths.js b/plugins/reusePaths.js index 4d91d6f9d..3e8556dd4 100644 --- a/plugins/reusePaths.js +++ b/plugins/reusePaths.js @@ -26,6 +26,13 @@ exports.fn = () => { */ const paths = new Map(); + /** + * Set of hrefs that reference the id of another node. + * + * @type {Set} + */ + const hrefs = new Set(); + return { element: { enter: (node) => { @@ -41,12 +48,23 @@ exports.fn = () => { } list.push(node); } + + if (node.name === 'use') { + for (const name of ['href', 'xlink:href']) { + const href = node.attributes[name]; + + if (href != null && href.startsWith('#') && href.length > 1) { + hrefs.add(href.slice(1)); + } + } + } }, exit: (node, parentNode) => { if (node.name === 'svg' && parentNode.type === 'root') { /** * @type {XastElement} + * @see https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs */ const defsTag = { type: 'element', @@ -74,7 +92,8 @@ exports.fn = () => { }; delete reusablePath.attributes.transform; let id; - if (reusablePath.attributes.id == null) { + const reusablePathId = reusablePath.attributes.id; + if (reusablePathId == null || hrefs.has(reusablePathId)) { id = 'reuse-' + index; index += 1; reusablePath.attributes.id = id; diff --git a/test/plugins/reusePaths.04.svg b/test/plugins/reusePaths.04.svg new file mode 100644 index 000000000..a96d550c4 --- /dev/null +++ b/test/plugins/reusePaths.04.svg @@ -0,0 +1,40 @@ +Don't remove and reuse the ID of the duplicate path if it's already being linked +in an href by another node. + +=== + + + + + + + + + + + + + + + + +@@@ + + + + + + + + + + + + + + + + + +