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.
+
+===
+
+
+
+@@@
+
+