fix: trim trailing blank lines from tile/sidebar snapshot previews
Sessions with cursor near the top (e.g. just a prompt) have 18+ empty lines below. slice(-20) grabbed all blanks, making previews appear empty. Fix: pop trailing blank lines after slicing so the pre element contains only meaningful content. CSS bottom:0 anchors it correctly. Tests: 4 new tests cover content-at-top trimming and all-blank edge case.
This commit is contained in:
+15
-2
@@ -526,7 +526,14 @@ function buildTileHTML(session, index, mobile) {
|
||||
// Last N lines of snapshot — show more in fit mode so tall tiles fill
|
||||
const snapshot = session.snapshot || '';
|
||||
var _lineCount = (ds.viewMode === 'fit') ? -80 : -20;
|
||||
const lastLines = snapshot.split('\n').slice(_lineCount).join('\n');
|
||||
var lines = snapshot.split('\n').slice(_lineCount);
|
||||
// Trim trailing blank lines — sessions with cursor near the top have mostly empty
|
||||
// lines at the bottom, making the preview appear blank. Removing them lets the
|
||||
// CSS `position: absolute; bottom: 0` anchor the meaningful content correctly.
|
||||
while (lines.length > 0 && lines[lines.length - 1].trim() === '') {
|
||||
lines.pop();
|
||||
}
|
||||
const lastLines = lines.join('\n');
|
||||
|
||||
const sourceUrlAttr = session.sourceUrl ? ` data-source-url="${escapeHtml(session.sourceUrl)}"` : '';
|
||||
return (
|
||||
@@ -577,7 +584,13 @@ function buildSidebarHTML(session, currentSession) {
|
||||
|
||||
// Last 20 lines of snapshot
|
||||
const snapshot = session.snapshot || '';
|
||||
const lastLines = snapshot.split('\n').slice(-20).join('\n');
|
||||
var sidebarLines = snapshot.split('\n').slice(-20);
|
||||
// Trim trailing blank lines — sessions with cursor near the top have mostly empty
|
||||
// lines at the bottom, making the preview appear blank.
|
||||
while (sidebarLines.length > 0 && sidebarLines[sidebarLines.length - 1].trim() === '') {
|
||||
sidebarLines.pop();
|
||||
}
|
||||
const lastLines = sidebarLines.join('\n');
|
||||
|
||||
return (
|
||||
`<article class="${classes}" data-session="${escapedName}" data-source-url="${escapeHtml(session.sourceUrl || '')}" tabindex="0" role="listitem">` +
|
||||
|
||||
@@ -4287,3 +4287,70 @@ test('CSS style.css .tile-time has opacity transition for crossfade', () => {
|
||||
'style.css must have session-tile:hover .tile-time for crossfade'
|
||||
);
|
||||
});
|
||||
|
||||
// --- Trailing blank line trimming in snapshot previews ---
|
||||
|
||||
test('buildTileHTML trims trailing blank lines so pre ends with last content line', () => {
|
||||
// Simulates a session where cursor is near the top: 2 content lines, then 18 blank lines.
|
||||
// slice(-20) grabs all 20 lines (2 content + 18 blanks).
|
||||
// Without trimming, the <pre> ends with blank lines (last meaningful content is invisible).
|
||||
// With trimming, the <pre> ends with the last non-blank line.
|
||||
const contentLines = ['$ tunnel up', ' forwarding 8443...'];
|
||||
const blankLines = new Array(18).fill('');
|
||||
const snapshot = contentLines.concat(blankLines).join('\n');
|
||||
|
||||
const session = { name: 'tunnel', snapshot };
|
||||
const html = app.buildTileHTML(session, 0, false);
|
||||
|
||||
// The pre element must contain the content lines
|
||||
assert.ok(html.includes('tunnel up'), 'tile preview must include content line');
|
||||
assert.ok(html.includes('forwarding 8443'), 'tile preview must include second content line');
|
||||
|
||||
// The pre should NOT end with blank lines (trailing whitespace trimmed)
|
||||
const preMatch = html.match(/<pre>([\s\S]*?)<\/pre>/);
|
||||
assert.ok(preMatch, '<pre> element must exist in tile HTML');
|
||||
const preContent = preMatch[1];
|
||||
const lastLine = preContent.split('\n').pop();
|
||||
assert.ok(lastLine.trim() !== '',
|
||||
'last line of pre content must not be blank after trimming trailing blank lines');
|
||||
});
|
||||
|
||||
test('buildSidebarHTML trims trailing blank lines so pre ends with last content line', () => {
|
||||
// Same scenario: 2 content lines at top, 18 blank lines below.
|
||||
const contentLines = ['$ tunnel up', ' forwarding 8443...'];
|
||||
const blankLines = new Array(18).fill('');
|
||||
const snapshot = contentLines.concat(blankLines).join('\n');
|
||||
|
||||
const session = { name: 'tunnel', snapshot, bell: { unseen_count: 0 } };
|
||||
const html = app.buildSidebarHTML(session, '');
|
||||
|
||||
assert.ok(html.includes('tunnel up'), 'sidebar preview must include content line');
|
||||
assert.ok(html.includes('forwarding 8443'), 'sidebar preview must include second content line');
|
||||
|
||||
const preMatch = html.match(/<pre>([\s\S]*?)<\/pre>/);
|
||||
assert.ok(preMatch, '<pre> element must exist in sidebar HTML');
|
||||
const preContent = preMatch[1];
|
||||
const lastLine = preContent.split('\n').pop();
|
||||
assert.ok(lastLine.trim() !== '',
|
||||
'last line of sidebar pre content must not be blank after trimming trailing blank lines');
|
||||
});
|
||||
|
||||
test('buildTileHTML renders empty pre when snapshot is entirely blank lines', () => {
|
||||
// Edge case: completely empty session — pre should be empty, not show garbage
|
||||
const snapshot = new Array(30).fill('').join('\n');
|
||||
const session = { name: 'empty-session', snapshot };
|
||||
const html = app.buildTileHTML(session, 0, false);
|
||||
const preMatch = html.match(/<pre>([\s\S]*?)<\/pre>/);
|
||||
assert.ok(preMatch, '<pre> element must exist');
|
||||
// pre content should be empty string (all blanks trimmed away)
|
||||
assert.strictEqual(preMatch[1], '', 'pre should be empty when snapshot has only blank lines');
|
||||
});
|
||||
|
||||
test('buildSidebarHTML renders empty pre when snapshot is entirely blank lines', () => {
|
||||
const snapshot = new Array(25).fill('').join('\n');
|
||||
const session = { name: 'empty-session', snapshot, bell: { unseen_count: 0 } };
|
||||
const html = app.buildSidebarHTML(session, '');
|
||||
const preMatch = html.match(/<pre>([\s\S]*?)<\/pre>/);
|
||||
assert.ok(preMatch, '<pre> element must exist');
|
||||
assert.strictEqual(preMatch[1], '', 'sidebar pre should be empty when snapshot has only blank lines');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user