From 3762dd12db3eaa86cb42f976293f0bc2ace80111 Mon Sep 17 00:00:00 2001 From: Teh PeGaSuS Date: Wed, 22 Apr 2026 23:17:04 +0200 Subject: [PATCH] Update app.js --- app.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app.js b/app.js index f7e90e6..a7e2bea 100644 --- a/app.js +++ b/app.js @@ -254,8 +254,15 @@ function ansiToHtml(text) { i++; continue; } // Collect all styles for one new span (stop at next reset or end) + // Partial-reset codes (bold-off, italic-off, default-fg, default-bg, etc.) + // treat the same as a full reset: close open spans and move on. + const PARTIAL_RESET = new Set([21,22,23,24,25,27,28,29,39,49,51,52,53,54,55]); + if (PARTIAL_RESET.has(codes[i])) { + if (spans > 0) { out += ''.repeat(spans); spans = 0; } + i++; continue; + } const st = []; - while (i < codes.length && codes[i] !== 0) { + while (i < codes.length && codes[i] !== 0 && !PARTIAL_RESET.has(codes[i])) { const c = codes[i]; if (c === 1) { st.push('font-weight:bold'); } else if (c === 3) { st.push('font-style:italic'); @@ -269,6 +276,7 @@ function ansiToHtml(text) { } else if (c >= 90 && c <= 97) { st.push(`color:${safeFg(ANSI16[c-90+8])}`); } else if (c >= 100 && c <= 107) { st.push(`background:${ANSI16[c-100+8]}`); } + // skip unrecognised codes silently i++; } if (st.length) { out += ``; spans++; } @@ -820,9 +828,9 @@ function renderNicklist(buf) { const box = el('nicklist'); box.innerHTML = ''; const nicks = Object.values(buf.nicks || {}).sort((a,b) => { - const w = p => p==='@'?0 : p==='+'?1 : 2; + const w = p => p==='~'?0 : p==='&'?1 : p==='@'?2 : p==='%'?3 : p==='+'?4 : 5; const d = w(a.prefix) - w(b.prefix); - return d !== 0 ? d : a.name.localeCompare(b.name); + return d !== 0 ? d : a.name.localeCompare(b.name, undefined, {sensitivity:'base'}); }); for (const nick of nicks) { const row = document.createElement('div'); @@ -1098,7 +1106,8 @@ document.addEventListener('DOMContentLoaded', () => { } // Media preview — delegated click on #messages - el('messages').addEventListener('click', e => { + // Media preview — document-level delegation + document.addEventListener('click', e => { const btn = e.target.closest('.media-toggle'); if (!btn) return; const url = btn.dataset.url.replace(/&/g,'&'); @@ -1112,6 +1121,8 @@ document.addEventListener('DOMContentLoaded', () => { if (type === 'img') { const img = document.createElement('img'); img.src = url; img.className = 'preview-img'; img.alt = 'image'; + img.title = 'Click to open full size'; + img.addEventListener('click', () => window.open(url, '_blank')); wrap.appendChild(img); } else { const vid = document.createElement('video'); @@ -1155,4 +1166,4 @@ document.addEventListener('DOMContentLoaded', () => { ['host','port','password'].forEach(id => el(id).addEventListener('keydown', e => { if (e.key === 'Enter') connect(); }) ); -}); +}); \ No newline at end of file