From a6acbcd8cd3173a2dafa0e3855633b75081b6120 Mon Sep 17 00:00:00 2001 From: Holger Berg <36001578+ogierMontanus@users.noreply.github.com> Date: Fri, 12 Sep 2025 10:29:36 +0200 Subject: [PATCH 1/2] Recursively handle spans in shadow DOM --- templates/pages/andersen-single.html | 89 ++++++++++++++-------------- 1 file changed, 44 insertions(+), 45 deletions(-) diff --git a/templates/pages/andersen-single.html b/templates/pages/andersen-single.html index 16b7667..547c32a 100644 --- a/templates/pages/andersen-single.html +++ b/templates/pages/andersen-single.html @@ -130,54 +130,53 @@ }; function markSpans(span) { - const content = span.querySelector('#content'); - const walker = document.createTreeWalker( - content, - NodeFilter.SHOW_ALL | NodeFilter.SHOW_TEXT - ); - - - const delNodes = []; - content.querySelectorAll('a.delSpan').forEach((anchor) => { - walker.currentNode = anchor; - const end = content.querySelector(anchor.hash); - while (walker.nextNode()) { - if (walker.currentNode === end) { - break; + let content = span.querySelector('#content'); + if (!content && span.shadowRoot) { + content = span.shadowRoot.querySelector('#content'); + } + if (!content) { + return; + } + + function process(root) { + const walker = document.createTreeWalker( + root, + NodeFilter.SHOW_ALL | NodeFilter.SHOW_TEXT + ); + + const wrapBetweenAnchors = (cls, name) => { + root.querySelectorAll(`a.${cls}`).forEach((anchor) => { + const nodes = []; + walker.currentNode = anchor; + const end = root.querySelector(anchor.hash); + while (walker.nextNode()) { + if (walker.currentNode === end) { + break; + } + if (walker.currentNode.nodeType === Node.TEXT_NODE) { + nodes.push(walker.currentNode); + } + } + nodes.forEach((node) => { + const wrapper = document.createElement('span'); + wrapper.className = name; + wrapper.appendChild(node.cloneNode()); + node.replaceWith(wrapper); + }); + }); + }; + + wrapBetweenAnchors('delSpan', 'deleted'); + wrapBetweenAnchors('addSpan', 'added'); + + root.querySelectorAll('*').forEach((el) => { + if (el.shadowRoot) { + process(el.shadowRoot); } - if (walker.currentNode.nodeType === Node.TEXT_NODE) { - delNodes.push(walker.currentNode); - } - } - - delNodes.forEach((node) => { - const wrapper = document.createElement('span'); - wrapper.className = 'deleted'; - wrapper.appendChild(node.cloneNode()); - node.replaceWith(wrapper); }); - }); - - const addNodes = []; - content.querySelectorAll('a.addSpan').forEach((anchor) => { - walker.currentNode = anchor; - const end = content.querySelector(anchor.hash); - while (walker.nextNode()) { - if (walker.currentNode === end) { - break; - } - if (walker.currentNode.nodeType === Node.TEXT_NODE) { - addNodes.push(walker.currentNode); - } - } + } - addNodes.forEach((node) => { - const wrapper = document.createElement('span'); - wrapper.className = 'added'; - wrapper.appendChild(node.cloneNode()); - node.replaceWith(wrapper); - }); - }); + process(content); }; window.addEventListener('load', () => { From 505faaccd6ca5fd5c7508c69d1ff98c89673f4c3 Mon Sep 17 00:00:00 2001 From: Holger Berg <36001578+ogierMontanus@users.noreply.github.com> Date: Fri, 12 Sep 2025 11:24:19 +0200 Subject: [PATCH 2/2] Handle anchors in nested shadow roots --- templates/pages/andersen-single.html | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/templates/pages/andersen-single.html b/templates/pages/andersen-single.html index 547c32a..91a7c46 100644 --- a/templates/pages/andersen-single.html +++ b/templates/pages/andersen-single.html @@ -139,16 +139,15 @@ } function process(root) { - const walker = document.createTreeWalker( - root, - NodeFilter.SHOW_ALL | NodeFilter.SHOW_TEXT - ); - const wrapBetweenAnchors = (cls, name) => { root.querySelectorAll(`a.${cls}`).forEach((anchor) => { const nodes = []; + const walker = document.createTreeWalker(root, NodeFilter.SHOW_ALL); walker.currentNode = anchor; const end = root.querySelector(anchor.hash); + if (!end) { + return; + } while (walker.nextNode()) { if (walker.currentNode === end) { break; @@ -169,6 +168,9 @@ wrapBetweenAnchors('delSpan', 'deleted'); wrapBetweenAnchors('addSpan', 'added'); + if (root instanceof Element && root.shadowRoot) { + process(root.shadowRoot); + } root.querySelectorAll('*').forEach((el) => { if (el.shadowRoot) { process(el.shadowRoot); @@ -190,4 +192,4 @@ }); - \ No newline at end of file +