1/*  DokuWiki MoaiEditor Cm_scroll.js file
2    Author  : MoaiTools <info@moaitools.org>
3    License : GPL 3 (http://www.gnu.org/licenses/gpl.html) */
4
5/*  This class implements the 'scroll.max', 'scroll.top' and 'scroll.smooth'
6    getters and setters required for every editor.
7
8    It also updates the vertical position of currently rendered lines to make
9    sure we work with precise values. We use an interval to throttle this process.
10
11    This is needed because CodeMirror will report inaccurate line positions when
12    they have not been rendered yet. So scrolling close to that part of the document
13    is required before an accurate value can be obtained.
14
15    If not corrected, this aproximation error adds up in large documents, which
16    results in a really bad scroll synchronization in lower parts of the page.
17*/
18MoaiEditor.CodemirrorScroll = class {
19
20    constructor(outer) {
21
22        // Arguments
23        this.outer = outer;
24
25        // Variables
26        this.smoothvalue = false;
27        this.range = null;       // {from, to} or null
28
29        // Interval
30        this.interval = setInterval(this.onInterval.bind(this), 250);
31    }
32
33    get max() {
34        // Return the maximum scroll possible
35        const info = this.outer.editor.getScrollInfo();
36        const height = info.height;                 // size of the scrollable area
37        const visHeight = info.clientHeight;        // size of the visible area (minus scrollbars)
38        return Math.abs(height-visHeight);
39    }
40    get height() {
41        // Return the height of the scrollable area
42        return this.outer.editor.getScrollInfo().height;
43    }
44
45    get top() {
46        return this.outer.editor.getScrollInfo().top;
47    }
48    set top(value) {
49        this.outer.scroller.scrollTop = value;
50        //this.outer.editor.scrollTo(null, value);
51    }
52
53    get smooth() {
54        return this.smoothvalue;
55    }
56    set smooth(boolean) {
57        var value = 'auto';
58        if (boolean)
59            value = 'smooth';
60        this.smoothvalue = boolean;
61        this.outer.scroller.style.scrollBehavior = value;
62    }
63
64    onScroll() {
65        const vp = this.outer.editor.getViewport();
66        if (this.range === null)
67            this.range = {from: vp.from, to: vp.to};
68        this.range.from = Math.min(this.range.from, vp.from);
69        this.range.to   = Math.max(this.range.to, vp.to);
70        this.debugLine();
71    }
72    onInterval() {
73        if (this.range !== null)
74            moaiEditor.matches.recalcScrollPoints(this.range);
75        this.range = null;
76    }
77
78    debugLine() {
79        // Exit if debugline is not enabled
80        const line = document.querySelector("#moai__debug div:nth-child(2)");
81        if (!line) return;
82        // Debug line
83        const info = this.outer.editor.getScrollInfo();
84        const scroll = Math.floor(info.top);
85        const height = info.height;
86        const viewport = info.clientHeight;
87        const text = "scroll:"+scroll+"  h:"+height+"  vp:"+viewport+"  max:"+this.max;
88        line.textContent = text;
89    }
90
91}; // End Class
92
93