From b80737347287c3060860f920fcd525c8e0f39ddc Mon Sep 17 00:00:00 2001 From: kgva CMS Date: Mon, 10 Aug 2026 21:24:13 +0000 Subject: [PATCH] fix: hide the de/en lang-switch on long prompt lines instead of clipping around it --- assets/js/shell.js | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/assets/js/shell.js b/assets/js/shell.js index 55fe07e..b33f9d1 100644 --- a/assets/js/shell.js +++ b/assets/js/shell.js @@ -15,33 +15,34 @@ // right so the left (older) part clips off terminal-style instead of wrapping. function keepEnd() { if (promptEl) promptEl.scrollLeft = promptEl.scrollWidth; } + // the lang-switch (de/en) is position:absolute top-right over the same row. + // reserving space for it (or clipping the line early to dodge it) wastes + // room on short lines — simpler to just hide it once a long line would + // reach it, and let it reappear the moment the line is short again. wired + // to a MutationObserver below so it re-checks on every change to the + // prompt text, no matter what set it (ghost, real typing, history, …). + function syncLangSwitch() { + var ls = document.querySelector(".lang-switch"); + if (!ls || !promptEl) return; + var lsRect = ls.getBoundingClientRect(); + var inRect = input.getBoundingClientRect(); + ls.style.visibility = (lsRect.width && inRect.right > lsRect.left - 8) ? "hidden" : ""; + } + new MutationObserver(syncLangSwitch).observe(input, { characterData: true, childList: true, subtree: true }); + // hard guarantee: the prompt is ALWAYS one line. CSS (nowrap + overflow:hidden) // is normally enough, but a long ghost command (long path + filename) can still // force the line to wrap on some viewports/browsers, which then bugs out the // layout below it. so on top of the CSS, actually shorten the text in the DOM: // clip from the FRONT (oldest part, same side as the terminal-scroll above) and // mark the cut with "…" — the leading verb ("cat "/"cd ") is allowed to go first. - // - // the lang-switch (de/en) is position:absolute top-right over the same row — - // CSS reserves padding-right for it, but that padding doesn't actually stop - // overflowing nowrap text (padding isn't a layout barrier for overflow), so a - // long enough line still slides under it. check the real rendered edges too, - // not just clientWidth, so the toggle at the far end is never covered. - function overlapsLangSwitch() { - var ls = document.querySelector(".lang-switch"); - if (!ls) return false; - var lsRect = ls.getBoundingClientRect(); - var inRect = input.getBoundingClientRect(); - return inRect.right > lsRect.left - 8; // 8px breathing room - } - function fits() { return promptEl.scrollWidth <= promptEl.clientWidth && !overlapsLangSwitch(); } function fitOneLine(text) { if (!promptEl) return text; promptEl.scrollLeft = 0; // measure from a clean, unscrolled state input.textContent = text; - if (fits()) return text; + if (promptEl.scrollWidth <= promptEl.clientWidth) return text; var shown = text; - while (shown.length > 1 && !fits()) { + while (shown.length > 1 && promptEl.scrollWidth > promptEl.clientWidth) { shown = shown.slice(1); input.textContent = "…" + shown; }