From bd750ceebb9008ecc0ed1e541ee9005f6af26302 Mon Sep 17 00:00:00 2001 From: Seth Falco Date: Sat, 23 Sep 2023 21:47:04 +0100 Subject: [PATCH] fix(reusePaths): dont reuse id if referenced in href (#1784) Fixes a bug where the reusePaths plugin would reuse the node ID that it's optimizing, but that ID was also referenced in a href elsewhere in the document, so it unintentionally applied the path to other nodes. --- plugins/reusePaths.js | 23 +++++++++++++++---- test/plugins/reusePaths.06.svg | 40 ++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 test/plugins/reusePaths.06.svg diff --git a/plugins/reusePaths.js b/plugins/reusePaths.js index d1cb53b14..022b1c036 100644 --- a/plugins/reusePaths.js +++ b/plugins/reusePaths.js @@ -37,6 +37,13 @@ exports.fn = () => { */ let svgDefs; + /** + * Set of hrefs that reference the id of another node. + * + * @type {Set} + */ + const hrefs = new Set(); + return { element: { enter: (node, parentNode) => { @@ -61,13 +68,20 @@ exports.fn = () => { ) { svgDefs = 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} - */ let defsTag = svgDefs; if (defsTag == null) { @@ -99,7 +113,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.06.svg b/test/plugins/reusePaths.06.svg new file mode 100644 index 000000000..a96d550c4 --- /dev/null +++ b/test/plugins/reusePaths.06.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. + +=== + + + + + + + + + + + + + + + + +@@@ + + + + + + + + + + + + + + + + + +