From 4da8b38fee04a15cd814028c6d0ebf69a2b326c2 Mon Sep 17 00:00:00 2001 From: johnkenny54 <45182853+johnkenny54@users.noreply.github.com> Date: Sat, 6 Jan 2024 06:55:24 -0800 Subject: [PATCH] fix(removeHiddenElems): dont remove node if children have referenced id (#1925) --- plugins/removeHiddenElems.js | 26 ++++++++++++++++++-------- test/plugins/removeHiddenElems.16.svg | 23 +++++++++++++++++++++++ test/plugins/removeHiddenElems.17.svg | 23 +++++++++++++++++++++++ test/plugins/removeHiddenElems.18.svg | 23 +++++++++++++++++++++++ 4 files changed, 87 insertions(+), 8 deletions(-) create mode 100644 test/plugins/removeHiddenElems.16.svg create mode 100644 test/plugins/removeHiddenElems.17.svg create mode 100644 test/plugins/removeHiddenElems.18.svg diff --git a/plugins/removeHiddenElems.js b/plugins/removeHiddenElems.js index 9713d5c52..995ecff65 100644 --- a/plugins/removeHiddenElems.js +++ b/plugins/removeHiddenElems.js @@ -91,6 +91,23 @@ export const fn = (root, params) => { */ let deoptimized = false; + /** + * Nodes can't be removed if they or any of their children have an id attribute that is referenced. + * @param {XastElement} node + * @returns boolean + */ + function canRemoveNonRenderingNode(node) { + if (allReferences.has(node.attributes.id)) { + return false; + } + for (const child of node.children) { + if (child.type === 'element' && !canRemoveNonRenderingNode(child)) { + return false; + } + } + return true; + } + /** * @param {XastChild} node * @param {XastParent} parentNode @@ -113,11 +130,6 @@ export const fn = (root, params) => { enter: (node, parentNode) => { // transparent non-rendering elements still apply where referenced if (nonRendering.has(node.name)) { - if (node.attributes.id == null) { - detachNodeFromParent(node, parentNode); - return visitSkip; - } - nonRenderedNodes.set(node, parentNode); return visitSkip; } @@ -419,9 +431,7 @@ export const fn = (root, params) => { nonRenderedNode, nonRenderedParent, ] of nonRenderedNodes.entries()) { - const id = nonRenderedNode.attributes.id; - - if (!allReferences.has(id)) { + if (canRemoveNonRenderingNode(nonRenderedNode)) { detachNodeFromParent(nonRenderedNode, nonRenderedParent); } } diff --git a/test/plugins/removeHiddenElems.16.svg b/test/plugins/removeHiddenElems.16.svg new file mode 100644 index 000000000..9795db0b9 --- /dev/null +++ b/test/plugins/removeHiddenElems.16.svg @@ -0,0 +1,23 @@ +Don't remove non-rendering elements if children have IDs. + +=== + + + + + + + + + + +@@@ + + + + + + + + + \ No newline at end of file diff --git a/test/plugins/removeHiddenElems.17.svg b/test/plugins/removeHiddenElems.17.svg new file mode 100644 index 000000000..ef3557e0a --- /dev/null +++ b/test/plugins/removeHiddenElems.17.svg @@ -0,0 +1,23 @@ +Don't remove used symbols. + +=== + + + + + + + + + + +@@@ + + + + + + + + + \ No newline at end of file diff --git a/test/plugins/removeHiddenElems.18.svg b/test/plugins/removeHiddenElems.18.svg new file mode 100644 index 000000000..ad1bb7f34 --- /dev/null +++ b/test/plugins/removeHiddenElems.18.svg @@ -0,0 +1,23 @@ +Preserve with referenced path. + +=== + + + + + + + + + + +@@@ + + + + + + + + +