Do not replace newlines inside of pre blocks (#4498) Fixes #4475

9a5235efcd41db249ec083ebdba735c89f940f23

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
1 files changed, +28 -1Showing whitespace changes
public/scripts/chats.js+28 -1
@@ -1758,7 +1758,34 @@ export function addDOMPurifyHooks() {
17581758
17591759 // Replace line breaks with <br> in unknown elements
17601760 if (node instanceof HTMLUnknownElement) {
17611761 node.innerHTML = node.innerHTML.trim().replaceAll('\n', '<br>');
1762+
1763+ /** @type {Text[]} */
1764+ const candidates = [];
1765+ const walker = document.createTreeWalker(node, NodeFilter.SHOW_TEXT);
1766+ while (walker.nextNode()) {
1767+ const textNode = /** @type {Text} */ (walker.currentNode);
1768+ if (!textNode.data.includes('\n')) continue;
1769+
1770+ // Skip if this text node is within a <pre> (any ancestor)
1771+ if (textNode.parentElement && textNode.parentElement.closest('pre')) continue;
1772+
1773+ candidates.push(textNode);
1774+ }
1775+
1776+ for (const textNode of candidates) {
1777+ const parts = textNode.data.split('\n');
1778+ const frag = document.createDocumentFragment();
1779+ parts.forEach((part, idx) => {
1780+ if (part.length) {
1781+ frag.appendChild(document.createTextNode(part));
1782+ }
1783+ if (idx < parts.length - 1) {
1784+ frag.appendChild(document.createElement('br'));
1785+ }
1786+ });
1787+ textNode.replaceWith(frag);
1788+ }
17621789 }
17631790
17641791 const isMediaAllowed = isExternalMediaAllowed();