annotate .cms/lib/codemirror/src/display/scroll_events.js @ 1:1d486627aa1e draft default tip

24.10
author Coffee CMS <info@coffee-cms.ru>
date Sat, 12 Oct 2024 02:51:39 +0000
parents 78edf6b517a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
1 import { chrome, chrome_version, gecko, ie, mac, presto, safari, webkit } from "../util/browser.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
2 import { e_preventDefault } from "../util/event.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
3
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
4 import { updateDisplaySimple } from "./update_display.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
5 import { setScrollLeft, updateScrollTop } from "./scrolling.js"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
6
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
7 // Since the delta values reported on mouse wheel events are
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
8 // unstandardized between browsers and even browser versions, and
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
9 // generally horribly unpredictable, this code starts by measuring
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
10 // the scroll effect that the first few mouse wheel events have,
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
11 // and, from that, detects the way it can convert deltas to pixel
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
12 // offsets afterwards.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
13 //
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
14 // The reason we want to know the amount a wheel event will scroll
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
15 // is that it gives us a chance to update the display before the
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
16 // actual scrolling happens, reducing flickering.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
17
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
18 let wheelSamples = 0, wheelPixelsPerUnit = null
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
19 // Fill in a browser-detected starting value on browsers where we
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
20 // know one. These don't have to be accurate -- the result of them
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
21 // being wrong would just be a slight flicker on the first wheel
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
22 // scroll (if it is large enough).
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
23 if (ie) wheelPixelsPerUnit = -.53
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
24 else if (gecko) wheelPixelsPerUnit = 15
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
25 else if (chrome) wheelPixelsPerUnit = -.7
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
26 else if (safari) wheelPixelsPerUnit = -1/3
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
27
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
28 function wheelEventDelta(e) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
29 let dx = e.wheelDeltaX, dy = e.wheelDeltaY
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
30 if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
31 if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
32 else if (dy == null) dy = e.wheelDelta
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
33 return {x: dx, y: dy}
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
34 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
35 export function wheelEventPixels(e) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
36 let delta = wheelEventDelta(e)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
37 delta.x *= wheelPixelsPerUnit
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
38 delta.y *= wheelPixelsPerUnit
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
39 return delta
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
40 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
41
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
42 export function onScrollWheel(cm, e) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
43 // On Chrome 102, viewport updates somehow stop wheel-based
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
44 // scrolling. Turning off pointer events during the scroll seems
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
45 // to avoid the issue.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
46 if (chrome && chrome_version == 102) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
47 if (cm.display.chromeScrollHack == null) cm.display.sizer.style.pointerEvents = "none"
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
48 else clearTimeout(cm.display.chromeScrollHack)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
49 cm.display.chromeScrollHack = setTimeout(() => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
50 cm.display.chromeScrollHack = null
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
51 cm.display.sizer.style.pointerEvents = ""
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
52 }, 100)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
53 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
54 let delta = wheelEventDelta(e), dx = delta.x, dy = delta.y
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
55 let pixelsPerUnit = wheelPixelsPerUnit
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
56 if (e.deltaMode === 0) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
57 dx = e.deltaX
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
58 dy = e.deltaY
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
59 pixelsPerUnit = 1
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
60 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
61
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
62 let display = cm.display, scroll = display.scroller
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
63 // Quit if there's nothing to scroll here
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
64 let canScrollX = scroll.scrollWidth > scroll.clientWidth
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
65 let canScrollY = scroll.scrollHeight > scroll.clientHeight
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
66 if (!(dx && canScrollX || dy && canScrollY)) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
67
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
68 // Webkit browsers on OS X abort momentum scrolls when the target
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
69 // of the scroll event is removed from the scrollable element.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
70 // This hack (see related code in patchDisplay) makes sure the
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
71 // element is kept around.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
72 if (dy && mac && webkit) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
73 outer: for (let cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
74 for (let i = 0; i < view.length; i++) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
75 if (view[i].node == cur) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
76 cm.display.currentWheelTarget = cur
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
77 break outer
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
78 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
79 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
80 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
81 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
82
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
83 // On some browsers, horizontal scrolling will cause redraws to
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
84 // happen before the gutter has been realigned, causing it to
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
85 // wriggle around in a most unseemly way. When we have an
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
86 // estimated pixels/delta value, we just handle horizontal
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
87 // scrolling entirely here. It'll be slightly off from native, but
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
88 // better than glitching out.
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
89 if (dx && !gecko && !presto && pixelsPerUnit != null) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
90 if (dy && canScrollY)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
91 updateScrollTop(cm, Math.max(0, scroll.scrollTop + dy * pixelsPerUnit))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
92 setScrollLeft(cm, Math.max(0, scroll.scrollLeft + dx * pixelsPerUnit))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
93 // Only prevent default scrolling if vertical scrolling is
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
94 // actually possible. Otherwise, it causes vertical scroll
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
95 // jitter on OSX trackpads when deltaX is small and deltaY
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
96 // is large (issue #3579)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
97 if (!dy || (dy && canScrollY))
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
98 e_preventDefault(e)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
99 display.wheelStartX = null // Abort measurement, if in progress
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
100 return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
101 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
102
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
103 // 'Project' the visible viewport to cover the area that is being
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
104 // scrolled into view (if we know enough to estimate it).
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
105 if (dy && pixelsPerUnit != null) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
106 let pixels = dy * pixelsPerUnit
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
107 let top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
108 if (pixels < 0) top = Math.max(0, top + pixels - 50)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
109 else bot = Math.min(cm.doc.height, bot + pixels + 50)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
110 updateDisplaySimple(cm, {top: top, bottom: bot})
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
111 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
112
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
113 if (wheelSamples < 20 && e.deltaMode !== 0) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
114 if (display.wheelStartX == null) {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
115 display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
116 display.wheelDX = dx; display.wheelDY = dy
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
117 setTimeout(() => {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
118 if (display.wheelStartX == null) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
119 let movedX = scroll.scrollLeft - display.wheelStartX
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
120 let movedY = scroll.scrollTop - display.wheelStartY
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
121 let sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
122 (movedX && display.wheelDX && movedX / display.wheelDX)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
123 display.wheelStartX = display.wheelStartY = null
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
124 if (!sample) return
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
125 wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
126 ++wheelSamples
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
127 }, 200)
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
128 } else {
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
129 display.wheelDX += dx; display.wheelDY += dy
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
130 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
131 }
Coffee CMS <info@coffee-cms.ru>
parents:
diff changeset
132 }