From 392fa026ccb6131d9d43a0f47b1bf765eec68dae Mon Sep 17 00:00:00 2001 From: fen Date: Thu, 10 Sep 2026 12:12:40 -0500 Subject: [PATCH] Fix #194: gutter alignment and doubled line spacing in paste viewer - paste-lines.js: join .codeline spans with no separator; newline text nodes between display:block spans in the white-space:pre container each rendered as an extra empty line box, doubling visual line spacing and desyncing the gutter in both wrap and no-wrap modes - number only real lines: a paste ending in newline produced a phantom trailing number (6 for 5 lines) --- internal/web/static/paste-lines.js | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/internal/web/static/paste-lines.js b/internal/web/static/paste-lines.js index 0eac3d3..ea4e65e 100644 --- a/internal/web/static/paste-lines.js +++ b/internal/web/static/paste-lines.js @@ -12,8 +12,10 @@ return document.documentElement.hasAttribute('data-wrap'); }; - // Wrap each logical line (split on newline; spans never contain newlines - // because HighlightCode highlights per line) in a .codeline block. + // #194: join with NO separator. .codeline is display:block, so a '\n' + // text node between spans is an extra line box in the white-space:pre + // container — that doubled the visual line spacing and desynced the + // gutter in BOTH modes. function splitLines() { var html = body.innerHTML; var parts = html.split('\n'); @@ -21,13 +23,17 @@ for (var i = 0; i < parts.length; i++) { out.push('' + parts[i] + ''); } - body.innerHTML = out.join('\n'); + body.innerHTML = out.join(''); } function renumber() { var lines = body.querySelectorAll('.codeline'); + // #194: a paste ending in '\n' produces one trailing empty .codeline; + // number only real lines (like every editor) so the count matches. + var count = lines.length; + if (count > 1 && lines[count - 1].textContent === '') count--; var s = ''; - if (wrapOn() && lines.length) { + if (wrapOn() && count) { // Each logical line block occupies rows = height / line-height when // wrapped; its number sits on the first row and the remaining rows get // blank gutter lines so numbers stay aligned with line starts. @@ -37,7 +43,7 @@ var lh = parseFloat(getComputedStyle(body).lineHeight) || 1; gutter.textContent = ''; var frag = document.createDocumentFragment(); - for (var i = 0; i < lines.length; i++) { + for (var i = 0; i < count; i++) { var num = document.createElement('span'); num.className = 'gutline'; num.textContent = String(i + 1); @@ -52,8 +58,8 @@ } gutter.appendChild(frag); } else { - for (var k = 1; k <= lines.length; k++) s += k + '\n'; - gutter.textContent = lines.length ? s.slice(0, -1) : '1'; + for (var k = 1; k <= count; k++) s += k + '\n'; + gutter.textContent = count ? s.slice(0, -1) : '1'; } } -- 2.54.0