Something like this should be safer, modifies only SVGs:
document.querySelectorAll(".markdown-reading-view svg").forEach((svg) => {
svg.querySelectorAll("[id]").forEach((el) => {
const id = el.id;
const randomInt = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
svg.innerHTML = svg.innerHTML.replaceAll(id, `${id}-${randomInt}`);
})
});
This way it doesn’t touch the user written text, but also, because it doesn’t rewrite the whole reading view HTML, it keeps event references intact outside SVG elements.
And this way you could even use multiple SVGs which use clashing IDs.
At the moment, if you include 2 SVGs and one defines a gradient:
<linearGradient id="gradient" x1="0" x2="1" y1="0" y2="0">
<stop offset="0%" stop-color="black"/>
<stop offset="50%" stop-color="white"/>
<stop offset="100%" stop-color="black"/>
</linearGradient>
And the other SVG:
<linearGradient id="gradient" x1="0" x2="1" y1="0" y2="0">
<stop offset="0%" stop-color="red"/>
<stop offset="50%" stop-color="yellow"/>
<stop offset="100%" stop-color="red"/>
</linearGradient>
Then when the second SVG tries to use #gradient, it will actually refer to the gradient of the first SVG and so the second SVG will render incorrectly.
Maybe it could be a temporary fix until shadow DOM is implemented?