@xterm/xterm 6.1.0-beta.23 → 6.1.0-beta.230

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (160) hide show
  1. package/README.md +62 -38
  2. package/css/xterm.css +29 -22
  3. package/lib/xterm.js +1 -1
  4. package/lib/xterm.js.map +1 -1
  5. package/lib/xterm.mjs +8 -34
  6. package/lib/xterm.mjs.map +4 -4
  7. package/package.json +25 -22
  8. package/src/browser/AccessibilityManager.ts +11 -6
  9. package/src/browser/Clipboard.ts +6 -3
  10. package/src/browser/CoreBrowserTerminal.ts +147 -318
  11. package/src/browser/Dom.ts +178 -0
  12. package/src/browser/Linkifier.ts +11 -11
  13. package/src/browser/OscLinkProvider.ts +82 -14
  14. package/src/browser/RenderDebouncer.ts +2 -2
  15. package/src/browser/TimeBasedDebouncer.ts +2 -2
  16. package/src/browser/Types.ts +12 -11
  17. package/src/browser/Viewport.ts +55 -20
  18. package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
  19. package/src/browser/decorations/OverviewRulerRenderer.ts +33 -17
  20. package/src/browser/input/CompositionHelper.ts +44 -8
  21. package/src/browser/public/Terminal.ts +25 -28
  22. package/src/browser/renderer/dom/DomRenderer.ts +242 -76
  23. package/src/browser/renderer/dom/DomRendererRowFactory.ts +19 -13
  24. package/src/browser/renderer/dom/WidthCache.ts +54 -52
  25. package/src/browser/renderer/shared/Constants.ts +7 -0
  26. package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
  27. package/src/browser/renderer/shared/Types.ts +8 -2
  28. package/src/browser/scrollable/abstractScrollbar.ts +300 -0
  29. package/src/browser/scrollable/fastDomNode.ts +126 -0
  30. package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
  31. package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
  32. package/src/browser/scrollable/mouseEvent.ts +292 -0
  33. package/src/browser/scrollable/scrollable.ts +486 -0
  34. package/src/browser/scrollable/scrollableElement.ts +581 -0
  35. package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
  36. package/src/browser/scrollable/scrollbarArrow.ts +110 -0
  37. package/src/browser/scrollable/scrollbarState.ts +246 -0
  38. package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
  39. package/src/browser/scrollable/touch.ts +485 -0
  40. package/src/browser/scrollable/verticalScrollbar.ts +143 -0
  41. package/src/browser/scrollable/widget.ts +23 -0
  42. package/src/browser/services/CharSizeService.ts +2 -2
  43. package/src/browser/services/CoreBrowserService.ts +7 -5
  44. package/src/browser/services/KeyboardService.ts +67 -0
  45. package/src/browser/services/LinkProviderService.ts +1 -1
  46. package/src/browser/services/MouseCoordsService.ts +47 -0
  47. package/src/browser/services/MouseService.ts +518 -25
  48. package/src/browser/services/RenderService.ts +28 -16
  49. package/src/browser/services/SelectionService.ts +42 -35
  50. package/src/browser/services/Services.ts +40 -17
  51. package/src/browser/services/ThemeService.ts +2 -2
  52. package/src/common/Async.ts +141 -0
  53. package/src/common/CircularList.ts +2 -2
  54. package/src/common/Color.ts +8 -0
  55. package/src/common/CoreTerminal.ts +31 -21
  56. package/src/common/Event.ts +118 -0
  57. package/src/common/InputHandler.ts +283 -81
  58. package/src/common/Lifecycle.ts +113 -0
  59. package/src/common/Platform.ts +13 -3
  60. package/src/common/SortedList.ts +7 -3
  61. package/src/common/TaskQueue.ts +14 -5
  62. package/src/common/Types.ts +51 -31
  63. package/src/common/Version.ts +9 -0
  64. package/src/common/buffer/Buffer.ts +34 -19
  65. package/src/common/buffer/BufferLine.ts +133 -65
  66. package/src/common/buffer/BufferLineStringCache.ts +69 -0
  67. package/src/common/buffer/BufferSet.ts +11 -6
  68. package/src/common/buffer/CellData.ts +57 -0
  69. package/src/common/buffer/Marker.ts +2 -2
  70. package/src/common/buffer/Types.ts +6 -2
  71. package/src/common/data/EscapeSequences.ts +71 -70
  72. package/src/common/input/Keyboard.ts +14 -7
  73. package/src/common/input/KittyKeyboard.ts +526 -0
  74. package/src/common/input/Win32InputMode.ts +297 -0
  75. package/src/common/input/WriteBuffer.ts +69 -32
  76. package/src/common/input/XParseColor.ts +2 -2
  77. package/src/common/parser/ApcParser.ts +197 -0
  78. package/src/common/parser/Constants.ts +14 -4
  79. package/src/common/parser/DcsParser.ts +5 -5
  80. package/src/common/parser/EscapeSequenceParser.ts +205 -63
  81. package/src/common/parser/OscParser.ts +5 -5
  82. package/src/common/parser/Params.ts +27 -8
  83. package/src/common/parser/Types.ts +36 -2
  84. package/src/common/public/BufferLineApiView.ts +2 -2
  85. package/src/common/public/BufferNamespaceApi.ts +3 -3
  86. package/src/common/public/ParserApi.ts +3 -0
  87. package/src/common/services/BufferService.ts +14 -9
  88. package/src/common/services/CharsetService.ts +4 -0
  89. package/src/common/services/CoreService.ts +18 -4
  90. package/src/common/services/DecorationService.ts +258 -8
  91. package/src/common/services/LogService.ts +1 -31
  92. package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
  93. package/src/common/services/OptionsService.ts +13 -4
  94. package/src/common/services/ServiceRegistry.ts +9 -7
  95. package/src/common/services/Services.ts +49 -40
  96. package/src/common/services/UnicodeService.ts +1 -1
  97. package/typings/xterm.d.ts +318 -34
  98. package/src/common/TypedArrayUtils.ts +0 -17
  99. package/src/vs/base/browser/browser.ts +0 -141
  100. package/src/vs/base/browser/canIUse.ts +0 -49
  101. package/src/vs/base/browser/dom.ts +0 -2369
  102. package/src/vs/base/browser/fastDomNode.ts +0 -316
  103. package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
  104. package/src/vs/base/browser/iframe.ts +0 -135
  105. package/src/vs/base/browser/keyboardEvent.ts +0 -213
  106. package/src/vs/base/browser/mouseEvent.ts +0 -229
  107. package/src/vs/base/browser/touch.ts +0 -372
  108. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
  109. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
  110. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
  111. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
  112. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
  113. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
  114. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
  115. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
  116. package/src/vs/base/browser/ui/widget.ts +0 -57
  117. package/src/vs/base/browser/window.ts +0 -14
  118. package/src/vs/base/common/arrays.ts +0 -887
  119. package/src/vs/base/common/arraysFind.ts +0 -202
  120. package/src/vs/base/common/assert.ts +0 -71
  121. package/src/vs/base/common/async.ts +0 -1992
  122. package/src/vs/base/common/cancellation.ts +0 -148
  123. package/src/vs/base/common/charCode.ts +0 -450
  124. package/src/vs/base/common/collections.ts +0 -140
  125. package/src/vs/base/common/decorators.ts +0 -130
  126. package/src/vs/base/common/equals.ts +0 -146
  127. package/src/vs/base/common/errors.ts +0 -303
  128. package/src/vs/base/common/event.ts +0 -1778
  129. package/src/vs/base/common/functional.ts +0 -32
  130. package/src/vs/base/common/hash.ts +0 -316
  131. package/src/vs/base/common/iterator.ts +0 -159
  132. package/src/vs/base/common/keyCodes.ts +0 -526
  133. package/src/vs/base/common/keybindings.ts +0 -284
  134. package/src/vs/base/common/lazy.ts +0 -47
  135. package/src/vs/base/common/lifecycle.ts +0 -801
  136. package/src/vs/base/common/linkedList.ts +0 -142
  137. package/src/vs/base/common/map.ts +0 -202
  138. package/src/vs/base/common/numbers.ts +0 -98
  139. package/src/vs/base/common/observable.ts +0 -76
  140. package/src/vs/base/common/observableInternal/api.ts +0 -31
  141. package/src/vs/base/common/observableInternal/autorun.ts +0 -281
  142. package/src/vs/base/common/observableInternal/base.ts +0 -489
  143. package/src/vs/base/common/observableInternal/debugName.ts +0 -145
  144. package/src/vs/base/common/observableInternal/derived.ts +0 -428
  145. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
  146. package/src/vs/base/common/observableInternal/logging.ts +0 -328
  147. package/src/vs/base/common/observableInternal/promise.ts +0 -209
  148. package/src/vs/base/common/observableInternal/utils.ts +0 -610
  149. package/src/vs/base/common/platform.ts +0 -281
  150. package/src/vs/base/common/scrollable.ts +0 -522
  151. package/src/vs/base/common/sequence.ts +0 -34
  152. package/src/vs/base/common/stopwatch.ts +0 -43
  153. package/src/vs/base/common/strings.ts +0 -557
  154. package/src/vs/base/common/symbols.ts +0 -9
  155. package/src/vs/base/common/uint.ts +0 -59
  156. package/src/vs/patches/nls.ts +0 -90
  157. package/src/vs/typings/base-common.d.ts +0 -20
  158. package/src/vs/typings/require.d.ts +0 -42
  159. package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
  160. package/src/vs/typings/vscode-globals-product.d.ts +0 -33
@@ -1,372 +0,0 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the MIT License. See License.txt in the project root for license information.
4
- *--------------------------------------------------------------------------------------------*/
5
-
6
- import * as DomUtils from 'vs/base/browser/dom';
7
- import { mainWindow } from 'vs/base/browser/window';
8
- import * as arrays from 'vs/base/common/arrays';
9
- import { memoize } from 'vs/base/common/decorators';
10
- import { Event as EventUtils } from 'vs/base/common/event';
11
- import { Disposable, IDisposable, markAsSingleton, toDisposable } from 'vs/base/common/lifecycle';
12
- import { LinkedList } from 'vs/base/common/linkedList';
13
-
14
- export namespace EventType {
15
- export const Tap = '-xterm-gesturetap';
16
- export const Change = '-xterm-gesturechange';
17
- export const Start = '-xterm-gesturestart';
18
- export const End = '-xterm-gesturesend';
19
- export const Contextmenu = '-xterm-gesturecontextmenu';
20
- }
21
-
22
- interface TouchData {
23
- id: number;
24
- initialTarget: EventTarget;
25
- initialTimeStamp: number;
26
- initialPageX: number;
27
- initialPageY: number;
28
- rollingTimestamps: number[];
29
- rollingPageX: number[];
30
- rollingPageY: number[];
31
- }
32
-
33
- export interface GestureEvent extends MouseEvent {
34
- initialTarget: EventTarget | undefined;
35
- translationX: number;
36
- translationY: number;
37
- pageX: number;
38
- pageY: number;
39
- tapCount: number;
40
- }
41
-
42
- interface Touch {
43
- identifier: number;
44
- screenX: number;
45
- screenY: number;
46
- clientX: number;
47
- clientY: number;
48
- pageX: number;
49
- pageY: number;
50
- radiusX: number;
51
- radiusY: number;
52
- rotationAngle: number;
53
- force: number;
54
- target: Element;
55
- }
56
-
57
- interface TouchList {
58
- [i: number]: Touch;
59
- length: number;
60
- item(index: number): Touch;
61
- identifiedTouch(id: number): Touch;
62
- }
63
-
64
- interface TouchEvent extends Event {
65
- touches: TouchList;
66
- targetTouches: TouchList;
67
- changedTouches: TouchList;
68
- }
69
-
70
- export class Gesture extends Disposable {
71
-
72
- private static readonly SCROLL_FRICTION = -0.005;
73
- private static INSTANCE: Gesture;
74
- private static readonly HOLD_DELAY = 700;
75
-
76
- private dispatched = false;
77
- private readonly targets = new LinkedList<HTMLElement>();
78
- private readonly ignoreTargets = new LinkedList<HTMLElement>();
79
- private handle: IDisposable | null;
80
-
81
- private readonly activeTouches: { [id: number]: TouchData };
82
-
83
- private _lastSetTapCountTime: number;
84
-
85
- private static readonly CLEAR_TAP_COUNT_TIME = 400; // ms
86
-
87
-
88
- private constructor() {
89
- super();
90
-
91
- this.activeTouches = {};
92
- this.handle = null;
93
- this._lastSetTapCountTime = 0;
94
-
95
- this._register(EventUtils.runAndSubscribe(DomUtils.onDidRegisterWindow, ({ window, disposables }) => {
96
- disposables.add(DomUtils.addDisposableListener(window.document, 'touchstart', (e: TouchEvent) => this.onTouchStart(e), { passive: false }));
97
- disposables.add(DomUtils.addDisposableListener(window.document, 'touchend', (e: TouchEvent) => this.onTouchEnd(window, e)));
98
- disposables.add(DomUtils.addDisposableListener(window.document, 'touchmove', (e: TouchEvent) => this.onTouchMove(e), { passive: false }));
99
- }, { window: mainWindow, disposables: this._store }));
100
- }
101
-
102
- public static addTarget(element: HTMLElement): IDisposable {
103
- if (!Gesture.isTouchDevice()) {
104
- return Disposable.None;
105
- }
106
- if (!Gesture.INSTANCE) {
107
- Gesture.INSTANCE = markAsSingleton(new Gesture());
108
- }
109
-
110
- const remove = Gesture.INSTANCE.targets.push(element);
111
- return toDisposable(remove);
112
- }
113
-
114
- public static ignoreTarget(element: HTMLElement): IDisposable {
115
- if (!Gesture.isTouchDevice()) {
116
- return Disposable.None;
117
- }
118
- if (!Gesture.INSTANCE) {
119
- Gesture.INSTANCE = markAsSingleton(new Gesture());
120
- }
121
-
122
- const remove = Gesture.INSTANCE.ignoreTargets.push(element);
123
- return toDisposable(remove);
124
- }
125
-
126
- @memoize
127
- static isTouchDevice(): boolean {
128
- // `'ontouchstart' in window` always evaluates to true with typescript's modern typings. This causes `window` to be
129
- // `never` later in `window.navigator`. That's why we need the explicit `window as Window` cast
130
- return 'ontouchstart' in mainWindow || navigator.maxTouchPoints > 0;
131
- }
132
-
133
- public override dispose(): void {
134
- if (this.handle) {
135
- this.handle.dispose();
136
- this.handle = null;
137
- }
138
-
139
- super.dispose();
140
- }
141
-
142
- private onTouchStart(e: TouchEvent): void {
143
- const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based.
144
-
145
- if (this.handle) {
146
- this.handle.dispose();
147
- this.handle = null;
148
- }
149
-
150
- for (let i = 0, len = e.targetTouches.length; i < len; i++) {
151
- const touch = e.targetTouches.item(i);
152
-
153
- this.activeTouches[touch.identifier] = {
154
- id: touch.identifier,
155
- initialTarget: touch.target,
156
- initialTimeStamp: timestamp,
157
- initialPageX: touch.pageX,
158
- initialPageY: touch.pageY,
159
- rollingTimestamps: [timestamp],
160
- rollingPageX: [touch.pageX],
161
- rollingPageY: [touch.pageY]
162
- };
163
-
164
- const evt = this.newGestureEvent(EventType.Start, touch.target);
165
- evt.pageX = touch.pageX;
166
- evt.pageY = touch.pageY;
167
- this.dispatchEvent(evt);
168
- }
169
-
170
- if (this.dispatched) {
171
- e.preventDefault();
172
- e.stopPropagation();
173
- this.dispatched = false;
174
- }
175
- }
176
-
177
- private onTouchEnd(targetWindow: Window, e: TouchEvent): void {
178
- const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based.
179
-
180
- const activeTouchCount = Object.keys(this.activeTouches).length;
181
-
182
- for (let i = 0, len = e.changedTouches.length; i < len; i++) {
183
-
184
- const touch = e.changedTouches.item(i);
185
-
186
- if (!this.activeTouches.hasOwnProperty(String(touch.identifier))) {
187
- console.warn('move of an UNKNOWN touch', touch);
188
- continue;
189
- }
190
-
191
- const data = this.activeTouches[touch.identifier],
192
- holdTime = Date.now() - data.initialTimeStamp;
193
-
194
- if (holdTime < Gesture.HOLD_DELAY
195
- && Math.abs(data.initialPageX - arrays.tail(data.rollingPageX)!) < 30
196
- && Math.abs(data.initialPageY - arrays.tail(data.rollingPageY)!) < 30) {
197
-
198
- const evt = this.newGestureEvent(EventType.Tap, data.initialTarget);
199
- evt.pageX = arrays.tail(data.rollingPageX)!;
200
- evt.pageY = arrays.tail(data.rollingPageY)!;
201
- this.dispatchEvent(evt);
202
-
203
- } else if (holdTime >= Gesture.HOLD_DELAY
204
- && Math.abs(data.initialPageX - arrays.tail(data.rollingPageX)!) < 30
205
- && Math.abs(data.initialPageY - arrays.tail(data.rollingPageY)!) < 30) {
206
-
207
- const evt = this.newGestureEvent(EventType.Contextmenu, data.initialTarget);
208
- evt.pageX = arrays.tail(data.rollingPageX)!;
209
- evt.pageY = arrays.tail(data.rollingPageY)!;
210
- this.dispatchEvent(evt);
211
-
212
- } else if (activeTouchCount === 1) {
213
- const finalX = arrays.tail(data.rollingPageX)!;
214
- const finalY = arrays.tail(data.rollingPageY)!;
215
-
216
- const deltaT = arrays.tail(data.rollingTimestamps)! - data.rollingTimestamps[0];
217
- const deltaX = finalX - data.rollingPageX[0];
218
- const deltaY = finalY - data.rollingPageY[0];
219
-
220
- // We need to get all the dispatch targets on the start of the inertia event
221
- const dispatchTo = [...this.targets].filter(t => data.initialTarget instanceof Node && t.contains(data.initialTarget));
222
- this.inertia(targetWindow, dispatchTo, timestamp, // time now
223
- Math.abs(deltaX) / deltaT, // speed
224
- deltaX > 0 ? 1 : -1, // x direction
225
- finalX, // x now
226
- Math.abs(deltaY) / deltaT, // y speed
227
- deltaY > 0 ? 1 : -1, // y direction
228
- finalY // y now
229
- );
230
- }
231
-
232
-
233
- this.dispatchEvent(this.newGestureEvent(EventType.End, data.initialTarget));
234
- // forget about this touch
235
- delete this.activeTouches[touch.identifier];
236
- }
237
-
238
- if (this.dispatched) {
239
- e.preventDefault();
240
- e.stopPropagation();
241
- this.dispatched = false;
242
- }
243
- }
244
-
245
- private newGestureEvent(type: string, initialTarget?: EventTarget): GestureEvent {
246
- const event = document.createEvent('CustomEvent') as unknown as GestureEvent;
247
- event.initEvent(type, false, true);
248
- event.initialTarget = initialTarget;
249
- event.tapCount = 0;
250
- return event;
251
- }
252
-
253
- private dispatchEvent(event: GestureEvent): void {
254
- if (event.type === EventType.Tap) {
255
- const currentTime = (new Date()).getTime();
256
- let setTapCount = 0;
257
- if (currentTime - this._lastSetTapCountTime > Gesture.CLEAR_TAP_COUNT_TIME) {
258
- setTapCount = 1;
259
- } else {
260
- setTapCount = 2;
261
- }
262
-
263
- this._lastSetTapCountTime = currentTime;
264
- event.tapCount = setTapCount;
265
- } else if (event.type === EventType.Change || event.type === EventType.Contextmenu) {
266
- // tap is canceled by scrolling or context menu
267
- this._lastSetTapCountTime = 0;
268
- }
269
-
270
- if (event.initialTarget instanceof Node) {
271
- for (const ignoreTarget of this.ignoreTargets) {
272
- if (ignoreTarget.contains(event.initialTarget)) {
273
- return;
274
- }
275
- }
276
-
277
- const targets: [number, HTMLElement][] = [];
278
- for (const target of this.targets) {
279
- if (target.contains(event.initialTarget)) {
280
- let depth = 0;
281
- let now: Node | null = event.initialTarget;
282
- while (now && now !== target) {
283
- depth++;
284
- now = now.parentElement;
285
- }
286
- targets.push([depth, target]);
287
- }
288
- }
289
-
290
- targets.sort((a, b) => a[0] - b[0]);
291
-
292
- for (const [_, target] of targets) {
293
- target.dispatchEvent(event);
294
- this.dispatched = true;
295
- }
296
- }
297
- }
298
-
299
- private inertia(targetWindow: Window, dispatchTo: readonly EventTarget[], t1: number, vX: number, dirX: number, x: number, vY: number, dirY: number, y: number): void {
300
- this.handle = DomUtils.scheduleAtNextAnimationFrame(targetWindow, () => {
301
- const now = Date.now();
302
-
303
- // velocity: old speed + accel_over_time
304
- const deltaT = now - t1;
305
- let delta_pos_x = 0, delta_pos_y = 0;
306
- let stopped = true;
307
-
308
- vX += Gesture.SCROLL_FRICTION * deltaT;
309
- vY += Gesture.SCROLL_FRICTION * deltaT;
310
-
311
- if (vX > 0) {
312
- stopped = false;
313
- delta_pos_x = dirX * vX * deltaT;
314
- }
315
-
316
- if (vY > 0) {
317
- stopped = false;
318
- delta_pos_y = dirY * vY * deltaT;
319
- }
320
-
321
- // dispatch translation event
322
- const evt = this.newGestureEvent(EventType.Change);
323
- evt.translationX = delta_pos_x;
324
- evt.translationY = delta_pos_y;
325
- dispatchTo.forEach(d => d.dispatchEvent(evt));
326
-
327
- if (!stopped) {
328
- this.inertia(targetWindow, dispatchTo, now, vX, dirX, x + delta_pos_x, vY, dirY, y + delta_pos_y);
329
- }
330
- });
331
- }
332
-
333
- private onTouchMove(e: TouchEvent): void {
334
- const timestamp = Date.now(); // use Date.now() because on FF e.timeStamp is not epoch based.
335
-
336
- for (let i = 0, len = e.changedTouches.length; i < len; i++) {
337
-
338
- const touch = e.changedTouches.item(i);
339
-
340
- if (!this.activeTouches.hasOwnProperty(String(touch.identifier))) {
341
- console.warn('end of an UNKNOWN touch', touch);
342
- continue;
343
- }
344
-
345
- const data = this.activeTouches[touch.identifier];
346
-
347
- const evt = this.newGestureEvent(EventType.Change, data.initialTarget);
348
- evt.translationX = touch.pageX - arrays.tail(data.rollingPageX)!;
349
- evt.translationY = touch.pageY - arrays.tail(data.rollingPageY)!;
350
- evt.pageX = touch.pageX;
351
- evt.pageY = touch.pageY;
352
- this.dispatchEvent(evt);
353
-
354
- // only keep a few data points, to average the final speed
355
- if (data.rollingPageX.length > 3) {
356
- data.rollingPageX.shift();
357
- data.rollingPageY.shift();
358
- data.rollingTimestamps.shift();
359
- }
360
-
361
- data.rollingPageX.push(touch.pageX);
362
- data.rollingPageY.push(touch.pageY);
363
- data.rollingTimestamps.push(timestamp);
364
- }
365
-
366
- if (this.dispatched) {
367
- e.preventDefault();
368
- e.stopPropagation();
369
- this.dispatched = false;
370
- }
371
- }
372
- }
@@ -1,303 +0,0 @@
1
- /*---------------------------------------------------------------------------------------------
2
- * Copyright (c) Microsoft Corporation. All rights reserved.
3
- * Licensed under the MIT License. See License.txt in the project root for license information.
4
- *--------------------------------------------------------------------------------------------*/
5
-
6
- import * as dom from 'vs/base/browser/dom';
7
- import { createFastDomNode, FastDomNode } from 'vs/base/browser/fastDomNode';
8
- import { GlobalPointerMoveMonitor } from 'vs/base/browser/globalPointerMoveMonitor';
9
- import { StandardWheelEvent } from 'vs/base/browser/mouseEvent';
10
- import { ScrollbarArrow, ScrollbarArrowOptions } from 'vs/base/browser/ui/scrollbar/scrollbarArrow';
11
- import { ScrollbarState } from 'vs/base/browser/ui/scrollbar/scrollbarState';
12
- import { ScrollbarVisibilityController } from 'vs/base/browser/ui/scrollbar/scrollbarVisibilityController';
13
- import { Widget } from 'vs/base/browser/ui/widget';
14
- import * as platform from 'vs/base/common/platform';
15
- import { INewScrollPosition, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
16
-
17
- /**
18
- * The orthogonal distance to the slider at which dragging "resets". This implements "snapping"
19
- */
20
- const POINTER_DRAG_RESET_DISTANCE = 140;
21
-
22
- export interface ISimplifiedPointerEvent {
23
- buttons: number;
24
- pageX: number;
25
- pageY: number;
26
- }
27
-
28
- export interface ScrollbarHost {
29
- onMouseWheel(mouseWheelEvent: StandardWheelEvent): void;
30
- onDragStart(): void;
31
- onDragEnd(): void;
32
- }
33
-
34
- export interface AbstractScrollbarOptions {
35
- lazyRender: boolean;
36
- host: ScrollbarHost;
37
- scrollbarState: ScrollbarState;
38
- visibility: ScrollbarVisibility;
39
- extraScrollbarClassName: string;
40
- scrollable: Scrollable;
41
- scrollByPage: boolean;
42
- }
43
-
44
- export abstract class AbstractScrollbar extends Widget {
45
-
46
- protected _host: ScrollbarHost;
47
- protected _scrollable: Scrollable;
48
- protected _scrollByPage: boolean;
49
- private _lazyRender: boolean;
50
- protected _scrollbarState: ScrollbarState;
51
- protected _visibilityController: ScrollbarVisibilityController;
52
- private _pointerMoveMonitor: GlobalPointerMoveMonitor;
53
-
54
- public domNode: FastDomNode<HTMLElement>;
55
- public slider!: FastDomNode<HTMLElement>;
56
-
57
- protected _shouldRender: boolean;
58
-
59
- constructor(opts: AbstractScrollbarOptions) {
60
- super();
61
- this._lazyRender = opts.lazyRender;
62
- this._host = opts.host;
63
- this._scrollable = opts.scrollable;
64
- this._scrollByPage = opts.scrollByPage;
65
- this._scrollbarState = opts.scrollbarState;
66
- this._visibilityController = this._register(new ScrollbarVisibilityController(opts.visibility, 'visible scrollbar ' + opts.extraScrollbarClassName, 'invisible scrollbar ' + opts.extraScrollbarClassName));
67
- this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());
68
- this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());
69
- this._shouldRender = true;
70
- this.domNode = createFastDomNode(document.createElement('div'));
71
- this.domNode.setAttribute('role', 'presentation');
72
- this.domNode.setAttribute('aria-hidden', 'true');
73
-
74
- this._visibilityController.setDomNode(this.domNode);
75
- this.domNode.setPosition('absolute');
76
-
77
- this._register(dom.addDisposableListener(this.domNode.domNode, dom.EventType.POINTER_DOWN, (e: PointerEvent) => this._domNodePointerDown(e)));
78
- }
79
-
80
- // ----------------- creation
81
-
82
- /**
83
- * Creates the dom node for an arrow & adds it to the container
84
- */
85
- protected _createArrow(opts: ScrollbarArrowOptions): void {
86
- const arrow = this._register(new ScrollbarArrow(opts));
87
- this.domNode.domNode.appendChild(arrow.bgDomNode);
88
- this.domNode.domNode.appendChild(arrow.domNode);
89
- }
90
-
91
- /**
92
- * Creates the slider dom node, adds it to the container & hooks up the events
93
- */
94
- protected _createSlider(top: number, left: number, width: number | undefined, height: number | undefined): void {
95
- this.slider = createFastDomNode(document.createElement('div'));
96
- this.slider.setClassName('slider');
97
- this.slider.setPosition('absolute');
98
- this.slider.setTop(top);
99
- this.slider.setLeft(left);
100
- if (typeof width === 'number') {
101
- this.slider.setWidth(width);
102
- }
103
- if (typeof height === 'number') {
104
- this.slider.setHeight(height);
105
- }
106
- this.slider.setLayerHinting(true);
107
- this.slider.setContain('strict');
108
-
109
- this.domNode.domNode.appendChild(this.slider.domNode);
110
-
111
- this._register(dom.addDisposableListener(
112
- this.slider.domNode,
113
- dom.EventType.POINTER_DOWN,
114
- (e: PointerEvent) => {
115
- if (e.button === 0) {
116
- e.preventDefault();
117
- this._sliderPointerDown(e);
118
- }
119
- }
120
- ));
121
-
122
- this.onclick(this.slider.domNode, e => {
123
- if (e.leftButton) {
124
- e.stopPropagation();
125
- }
126
- });
127
- }
128
-
129
- // ----------------- Update state
130
-
131
- protected _onElementSize(visibleSize: number): boolean {
132
- if (this._scrollbarState.setVisibleSize(visibleSize)) {
133
- this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());
134
- this._shouldRender = true;
135
- if (!this._lazyRender) {
136
- this.render();
137
- }
138
- }
139
- return this._shouldRender;
140
- }
141
-
142
- protected _onElementScrollSize(elementScrollSize: number): boolean {
143
- if (this._scrollbarState.setScrollSize(elementScrollSize)) {
144
- this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());
145
- this._shouldRender = true;
146
- if (!this._lazyRender) {
147
- this.render();
148
- }
149
- }
150
- return this._shouldRender;
151
- }
152
-
153
- protected _onElementScrollPosition(elementScrollPosition: number): boolean {
154
- if (this._scrollbarState.setScrollPosition(elementScrollPosition)) {
155
- this._visibilityController.setIsNeeded(this._scrollbarState.isNeeded());
156
- this._shouldRender = true;
157
- if (!this._lazyRender) {
158
- this.render();
159
- }
160
- }
161
- return this._shouldRender;
162
- }
163
-
164
- // ----------------- rendering
165
-
166
- public beginReveal(): void {
167
- this._visibilityController.setShouldBeVisible(true);
168
- }
169
-
170
- public beginHide(): void {
171
- this._visibilityController.setShouldBeVisible(false);
172
- }
173
-
174
- public render(): void {
175
- if (!this._shouldRender) {
176
- return;
177
- }
178
- this._shouldRender = false;
179
-
180
- this._renderDomNode(this._scrollbarState.getRectangleLargeSize(), this._scrollbarState.getRectangleSmallSize());
181
- this._updateSlider(this._scrollbarState.getSliderSize(), this._scrollbarState.getArrowSize() + this._scrollbarState.getSliderPosition());
182
- }
183
- // ----------------- DOM events
184
-
185
- private _domNodePointerDown(e: PointerEvent): void {
186
- if (e.target !== this.domNode.domNode) {
187
- return;
188
- }
189
- this._onPointerDown(e);
190
- }
191
-
192
- public delegatePointerDown(e: PointerEvent): void {
193
- const domTop = this.domNode.domNode.getClientRects()[0].top;
194
- const sliderStart = domTop + this._scrollbarState.getSliderPosition();
195
- const sliderStop = domTop + this._scrollbarState.getSliderPosition() + this._scrollbarState.getSliderSize();
196
- const pointerPos = this._sliderPointerPosition(e);
197
- if (sliderStart <= pointerPos && pointerPos <= sliderStop) {
198
- // Act as if it was a pointer down on the slider
199
- if (e.button === 0) {
200
- e.preventDefault();
201
- this._sliderPointerDown(e);
202
- }
203
- } else {
204
- // Act as if it was a pointer down on the scrollbar
205
- this._onPointerDown(e);
206
- }
207
- }
208
-
209
- private _onPointerDown(e: PointerEvent): void {
210
- let offsetX: number;
211
- let offsetY: number;
212
- if (e.target === this.domNode.domNode && typeof e.offsetX === 'number' && typeof e.offsetY === 'number') {
213
- offsetX = e.offsetX;
214
- offsetY = e.offsetY;
215
- } else {
216
- const domNodePosition = dom.getDomNodePagePosition(this.domNode.domNode);
217
- offsetX = e.pageX - domNodePosition.left;
218
- offsetY = e.pageY - domNodePosition.top;
219
- }
220
-
221
- const offset = this._pointerDownRelativePosition(offsetX, offsetY);
222
- this._setDesiredScrollPositionNow(
223
- this._scrollByPage
224
- ? this._scrollbarState.getDesiredScrollPositionFromOffsetPaged(offset)
225
- : this._scrollbarState.getDesiredScrollPositionFromOffset(offset)
226
- );
227
-
228
- if (e.button === 0) {
229
- // left button
230
- e.preventDefault();
231
- this._sliderPointerDown(e);
232
- }
233
- }
234
-
235
- private _sliderPointerDown(e: PointerEvent): void {
236
- if (!e.target || !(e.target instanceof Element)) {
237
- return;
238
- }
239
- const initialPointerPosition = this._sliderPointerPosition(e);
240
- const initialPointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(e);
241
- const initialScrollbarState = this._scrollbarState.clone();
242
- this.slider.toggleClassName('active', true);
243
-
244
- this._pointerMoveMonitor.startMonitoring(
245
- e.target,
246
- e.pointerId,
247
- e.buttons,
248
- (pointerMoveData: PointerEvent) => {
249
- const pointerOrthogonalPosition = this._sliderOrthogonalPointerPosition(pointerMoveData);
250
- const pointerOrthogonalDelta = Math.abs(pointerOrthogonalPosition - initialPointerOrthogonalPosition);
251
-
252
- if (platform.isWindows && pointerOrthogonalDelta > POINTER_DRAG_RESET_DISTANCE) {
253
- // The pointer has wondered away from the scrollbar => reset dragging
254
- this._setDesiredScrollPositionNow(initialScrollbarState.getScrollPosition());
255
- return;
256
- }
257
-
258
- const pointerPosition = this._sliderPointerPosition(pointerMoveData);
259
- const pointerDelta = pointerPosition - initialPointerPosition;
260
- this._setDesiredScrollPositionNow(initialScrollbarState.getDesiredScrollPositionFromDelta(pointerDelta));
261
- },
262
- () => {
263
- this.slider.toggleClassName('active', false);
264
- this._host.onDragEnd();
265
- }
266
- );
267
-
268
- this._host.onDragStart();
269
- }
270
-
271
- private _setDesiredScrollPositionNow(_desiredScrollPosition: number): void {
272
-
273
- const desiredScrollPosition: INewScrollPosition = {};
274
- this.writeScrollPosition(desiredScrollPosition, _desiredScrollPosition);
275
-
276
- this._scrollable.setScrollPositionNow(desiredScrollPosition);
277
- }
278
-
279
- public updateScrollbarSize(scrollbarSize: number): void {
280
- this._updateScrollbarSize(scrollbarSize);
281
- this._scrollbarState.setScrollbarSize(scrollbarSize);
282
- this._shouldRender = true;
283
- if (!this._lazyRender) {
284
- this.render();
285
- }
286
- }
287
-
288
- public isNeeded(): boolean {
289
- return this._scrollbarState.isNeeded();
290
- }
291
-
292
- // ----------------- Overwrite these
293
-
294
- protected abstract _renderDomNode(largeSize: number, smallSize: number): void;
295
- protected abstract _updateSlider(sliderSize: number, sliderPosition: number): void;
296
-
297
- protected abstract _pointerDownRelativePosition(offsetX: number, offsetY: number): number;
298
- protected abstract _sliderPointerPosition(e: ISimplifiedPointerEvent): number;
299
- protected abstract _sliderOrthogonalPointerPosition(e: ISimplifiedPointerEvent): number;
300
- protected abstract _updateScrollbarSize(size: number): void;
301
-
302
- public abstract writeScrollPosition(target: INewScrollPosition, scrollPosition: number): void;
303
- }