From a13c5541cccc3537492e5eb761b59da44b25aafc Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Tue, 4 Aug 2026 21:07:27 -0400 Subject: [PATCH] Pin the editor highlight overlay to the textarea so long confs scroll to the end --- Plugin/unraid/pages/scheduler.php | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/Plugin/unraid/pages/scheduler.php b/Plugin/unraid/pages/scheduler.php index 38866dc..72ecaeb 100644 --- a/Plugin/unraid/pages/scheduler.php +++ b/Plugin/unraid/pages/scheduler.php @@ -1172,8 +1172,14 @@ function vvFitRight() { const ed = document.getElementById('vv-editor'); if (ed.style.display !== 'none') { const _edH = Math.max(60, contentH - 38) + 'px'; - document.getElementById('vv-editor-body').style.height = _edH; + const _ta = document.getElementById('vv-editor-body'); + _ta.style.height = _edH; document.getElementById('vv-ln-gutter').style.height = _edH; + // Re-pin the overlay: this just changed the box it has to match, and vvSyncHlOverlay() + // does not run on resize. Without this the two drift apart again the moment the window + // changes size — see the comment there for what that costs. + const _ov = document.getElementById('vv-hl-overlay'); + if (_ov) _ov.style.height = _ta.clientHeight + 'px'; } const cf = document.getElementById('vv-confform'); if (cf.style.display !== 'none') { @@ -3065,6 +3071,23 @@ function vvSyncHlOverlay() { const ov = document.getElementById('vv-hl-overlay'); if (!ov || !document.getElementById('vv-editor').classList.contains('vv-editor-hl')) return; const ta = document.getElementById('vv-editor-body'); + + // Pin the overlay to the textarea's client box instead of letting it stretch to + // #vv-editor-inner. In highlight mode the textarea's text is transparent, so the overlay IS + // the visible document, and it is scrolled only by copying ta.scrollTop. That copy is exact + // only while both boxes are the same height — and nothing enforced that: vvFitRight() sizes + // the textarea to an explicit pixel height while the overlay inherits `top:0; bottom:0` from + // a flex:1 parent. When the parent came out taller, the overlay's scrollable range was the + // shorter of the two, so it reached its own end while the textarea kept going and the visible + // text froze a few lines short of the file. Reported against master.conf: stuck at 1683 of + // 1689, and unchanged by expanding or collapsing the job tree, which is what proved it a fixed + // offset rather than anything to do with contentH. + // + // clientHeight, not offsetHeight: it already excludes the horizontal scrollbar the textarea + // grows on long conf lines and the overlay never has, which was part of the same mismatch. + // With top and bottom both set, an explicit height wins and bottom is ignored. + ov.style.height = ta.clientHeight + 'px'; + let html = vvHl(ta.value, false) + '\n'; if (vvFindTerm) { html = vvMarkSearchInHtml(html, vvFindTerm, vvFindIdx);