From ff9791f028f7815d5e6e6348327c2094c56c4a81 Mon Sep 17 00:00:00 2001 From: Bryce Kwon Date: Sun, 25 Oct 2026 12:02:34 -1000 Subject: Keep the tabs on one row A window too narrow for the tabs wrapped the last of them onto a second row, held apart from the line under the others, as an iPhone showed on every repository page. The row now scrolls sideways instead, keeping the active tab in view and fading the side that hides more of them, and the tabs draw closer as the window narrows so all seven still fit at 360 pixels. --- assets/cgit.js | 46 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 42 insertions(+), 4 deletions(-) (limited to 'assets/cgit.js') diff --git a/assets/cgit.js b/assets/cgit.js index 807f15f..90f06c0 100644 --- a/assets/cgit.js +++ b/assets/cgit.js @@ -2,10 +2,11 @@ * The client side script that cgit serves with every page. Its main job is * to refresh the relative ages that cgit_print_age renders in * source/ui-shared.c, so the thresholds, suffixes and class names tabulated - * below mirror the constants there and the two have to move together. One - * smaller piece follows, the highlight laid over the source line a URL - * fragment names. Each piece is wrapped in a function of its own so that - * nothing is left behind in the global scope. + * below mirror the constants there and the two have to move together. Two + * smaller pieces follow, the highlight laid over the source line a URL + * fragment names, and the tabs kept in view on a window too narrow for them. + * Each piece is wrapped in a function of its own so that nothing is left + * behind in the global scope. */ (function () { @@ -166,3 +167,40 @@ window.cgit = window.cgit || {}; window.cgit.highlightLines = place_bar; })(); + +/* + * The tabs scroll sideways when the window is too narrow for them, so the + * active one is brought into view, and the edge past which more tabs are + * hidden is faded to show that the row goes on. + */ + +(function () { + +function fade_tabs(list) { + var hidden = list.scrollWidth - list.clientWidth; + + // A fractional scroll position can stop a pixel short of either end. + list.classList.toggle("fade-start", list.scrollLeft > 1); + list.classList.toggle("fade-end", list.scrollLeft < hidden - 1); +} + +function fit_tabs() { + var list = document.querySelector("nav.tabs ul"); + var active, list_box, tab_box; + + if (!list) + return; + active = list.querySelector("a.active"); + if (active && list.scrollWidth > list.clientWidth) { + list_box = list.getBoundingClientRect(); + tab_box = active.getBoundingClientRect(); + list.scrollLeft += tab_box.left - list_box.left - (list_box.width - tab_box.width) / 2; + } + fade_tabs(list); + list.addEventListener("scroll", function () { fade_tabs(list); }, { passive: true }); + window.addEventListener("resize", function () { fade_tabs(list); }, false); +} + +document.addEventListener("DOMContentLoaded", fit_tabs, false); + +})(); -- cgit 2.9.2