From 86f40ff6aed9e89cdaf066e5bd703c6cf57138db Mon Sep 17 00:00:00 2001 From: Ruben Carlo Benante Date: Wed, 8 Jul 2026 10:01:19 -0300 Subject: [PATCH] drive top-scrollbar layout() from a single ResizeObserver --- Asset/js/top-scrollbar.js | 47 ++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/Asset/js/top-scrollbar.js b/Asset/js/top-scrollbar.js index 49997a7..18db20e 100644 --- a/Asset/js/top-scrollbar.js +++ b/Asset/js/top-scrollbar.js @@ -115,6 +115,7 @@ if (c && c.parentNode && track.nextSibling !== c) { c.parentNode.insertBefore(track, c); } + observeSizes(); } // Board scrolled by any other means -> keep the thumb in sync. Capture-phase on @@ -185,18 +186,48 @@ positionThumb(m, thumbW); }); - window.addEventListener("resize", layout); + // Single source of truth for recomputing the thumb: a ResizeObserver on the container + // (viewport) and #board (content). It fires exactly when the width settles/changes -- the + // right moment -- which also fixes the stale thumb from the first layout() running before the + // board finished sizing. Both are replaced on a board refresh, so re-observe the current ones + // (from reattachTrack). Without ResizeObserver, fall back to a window resize listener. + var sizeObserver = window.ResizeObserver ? new ResizeObserver(function () { layout(); }) : null; + var observedContainer = null; + var observedBoard = null; - // Observe the STABLE parent so we keep working after #board-container is replaced by - // a card move / AJAX polling; re-seat the track and recompute sizes on any change. - if (window.MutationObserver) { - new MutationObserver(function () { - reattachTrack(); + function observeSizes() { + if (!sizeObserver) { layout(); - }).observe(boardParent, { childList: true, subtree: true }); + return; + } + + var c = getContainer(); + var b = document.getElementById("board"); + + if (c && c !== observedContainer) { + if (observedContainer) { sizeObserver.unobserve(observedContainer); } + sizeObserver.observe(c); + observedContainer = c; + } + + if (b && b !== observedBoard) { + if (observedBoard) { sizeObserver.unobserve(observedBoard); } + sizeObserver.observe(b); + observedBoard = b; + } } - layout(); + if (!sizeObserver) { + window.addEventListener("resize", layout); + } + + // Re-seat the track and re-observe after #board-container is replaced by a card move / AJAX + // polling (we watch the STABLE parent, since the container itself is swapped out). + if (window.MutationObserver) { + new MutationObserver(reattachTrack).observe(boardParent, { childList: true, subtree: true }); + } + + observeSizes(); } if (document.readyState === "loading") {