/* DokuWiki MoaiEditor Cm_scroll.js file Version : 0.5 (May 5, 2026) Author : MoaiTools License : GPL 3 (http://www.gnu.org/licenses/gpl.html) */ /* This class implements the 'scroll.max', 'scroll.top' and 'scroll.smooth' getters and setters required for every editor. It also updates the vertical position of currently rendered lines to make sure we work with precise values. We use an interval to throttle this process. This is needed because CodeMirror will report inaccurate line positions when they have not been rendered yet. So scrolling close to that part of the document is required before an accurate value can be obtained. If not corrected, this aproximation error adds up in large documents, which results in a really bad scroll synchronization in lower parts of the page. */ MoaiEditor.CodemirrorScroll = class { constructor(outer) { // Arguments this.outer = outer; // Variables this.smoothvalue = false; this.range = null; // {from, to} or null // Interval this.interval = setInterval(this.onInterval.bind(this), 250); } // ──────────────────────────────────── get max() { // Return the maximum scroll possible const info = this.outer.editor.getScrollInfo(); const height = info.height; // size of the scrollable area const visHeight = info.clientHeight; // size of the visible area (minus scrollbars) return Math.abs(height-visHeight); } get height() { // Return the height of the scrollable area return this.outer.editor.getScrollInfo().height; } // ──────────────────────────────────── get top() { return this.outer.editor.getScrollInfo().top; } set top(value) { this.outer.scroller.scrollTop = value; //this.outer.editor.scrollTo(null, value); } // ──────────────────────────────────── get smooth() { return this.smoothvalue; } set smooth(boolean) { var value = 'auto'; if (boolean) value = 'smooth'; this.smoothvalue = boolean; this.outer.scroller.style.scrollBehavior = value; } // ──────────────────────────────────── onScroll() { const vp = this.outer.editor.getViewport(); if (this.range === null) this.range = {from: vp.from, to: vp.to}; this.range.from = Math.min(this.range.from, vp.from); this.range.to = Math.max(this.range.to, vp.to); this.debugLine(); } onInterval() { if (this.range !== null) moaiEditor.matches.recalcScrollPoints(this.range); this.range = null; } // ──────────────────────────────────── debugLine() { // Exit if debugline is not enabled const line = document.querySelector("#moai__debug div:nth-child(2)"); if (!line) return; // Debug line const info = this.outer.editor.getScrollInfo(); const scroll = Math.floor(info.top); const height = info.height; const viewport = info.clientHeight; const text = "scroll:"+scroll+" h:"+height+" vp:"+viewport+" max:"+this.max; line.textContent = text; } }; // End Class