@xterm/xterm 5.6.0-beta.43 → 5.6.0-beta.45

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 (82) hide show
  1. package/css/xterm.css +65 -4
  2. package/lib/xterm.js +1 -1
  3. package/lib/xterm.js.map +1 -1
  4. package/lib/xterm.mjs +34 -7
  5. package/lib/xterm.mjs.map +4 -4
  6. package/package.json +2 -2
  7. package/src/browser/CoreBrowserTerminal.ts +53 -68
  8. package/src/browser/Types.ts +4 -1
  9. package/src/browser/Viewport.ts +142 -370
  10. package/src/browser/decorations/OverviewRulerRenderer.ts +25 -35
  11. package/src/browser/renderer/shared/CharAtlasUtils.ts +4 -0
  12. package/src/browser/services/ThemeService.ts +10 -1
  13. package/src/browser/shared/Constants.ts +8 -0
  14. package/src/common/CoreTerminal.ts +7 -13
  15. package/src/common/Types.ts +0 -6
  16. package/src/common/services/BufferService.ts +2 -2
  17. package/src/common/services/CoreMouseService.ts +2 -0
  18. package/src/common/services/Services.ts +10 -3
  19. package/src/vs/base/browser/browser.ts +141 -0
  20. package/src/vs/base/browser/canIUse.ts +49 -0
  21. package/src/vs/base/browser/dom.ts +2369 -0
  22. package/src/vs/base/browser/fastDomNode.ts +316 -0
  23. package/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
  24. package/src/vs/base/browser/iframe.ts +135 -0
  25. package/src/vs/base/browser/keyboardEvent.ts +213 -0
  26. package/src/vs/base/browser/mouseEvent.ts +229 -0
  27. package/src/vs/base/browser/touch.ts +372 -0
  28. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
  29. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
  30. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
  31. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
  32. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
  33. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
  34. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
  35. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
  36. package/src/vs/base/browser/ui/widget.ts +57 -0
  37. package/src/vs/base/browser/window.ts +14 -0
  38. package/src/vs/base/common/arrays.ts +887 -0
  39. package/src/vs/base/common/arraysFind.ts +202 -0
  40. package/src/vs/base/common/assert.ts +71 -0
  41. package/src/vs/base/common/async.ts +1992 -0
  42. package/src/vs/base/common/cancellation.ts +148 -0
  43. package/src/vs/base/common/charCode.ts +450 -0
  44. package/src/vs/base/common/collections.ts +140 -0
  45. package/src/vs/base/common/decorators.ts +130 -0
  46. package/src/vs/base/common/equals.ts +146 -0
  47. package/src/vs/base/common/errors.ts +303 -0
  48. package/src/vs/base/common/event.ts +1762 -0
  49. package/src/vs/base/common/functional.ts +32 -0
  50. package/src/vs/base/common/hash.ts +316 -0
  51. package/src/vs/base/common/iterator.ts +159 -0
  52. package/src/vs/base/common/keyCodes.ts +526 -0
  53. package/src/vs/base/common/keybindings.ts +284 -0
  54. package/src/vs/base/common/lazy.ts +47 -0
  55. package/src/vs/base/common/lifecycle.ts +801 -0
  56. package/src/vs/base/common/linkedList.ts +142 -0
  57. package/src/vs/base/common/map.ts +202 -0
  58. package/src/vs/base/common/numbers.ts +98 -0
  59. package/src/vs/base/common/observable.ts +76 -0
  60. package/src/vs/base/common/observableInternal/api.ts +31 -0
  61. package/src/vs/base/common/observableInternal/autorun.ts +281 -0
  62. package/src/vs/base/common/observableInternal/base.ts +489 -0
  63. package/src/vs/base/common/observableInternal/debugName.ts +145 -0
  64. package/src/vs/base/common/observableInternal/derived.ts +428 -0
  65. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
  66. package/src/vs/base/common/observableInternal/logging.ts +328 -0
  67. package/src/vs/base/common/observableInternal/promise.ts +209 -0
  68. package/src/vs/base/common/observableInternal/utils.ts +610 -0
  69. package/src/vs/base/common/platform.ts +281 -0
  70. package/src/vs/base/common/scrollable.ts +522 -0
  71. package/src/vs/base/common/sequence.ts +34 -0
  72. package/src/vs/base/common/stopwatch.ts +43 -0
  73. package/src/vs/base/common/strings.ts +557 -0
  74. package/src/vs/base/common/symbols.ts +9 -0
  75. package/src/vs/base/common/uint.ts +59 -0
  76. package/src/vs/patches/nls.ts +90 -0
  77. package/src/vs/typings/base-common.d.ts +20 -0
  78. package/src/vs/typings/require.d.ts +42 -0
  79. package/src/vs/typings/thenable.d.ts +12 -0
  80. package/src/vs/typings/vscode-globals-nls.d.ts +36 -0
  81. package/src/vs/typings/vscode-globals-product.d.ts +33 -0
  82. package/typings/xterm.d.ts +25 -1
@@ -0,0 +1,165 @@
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 { ScrollbarVisibility } from 'vs/base/common/scrollable';
7
+
8
+ export interface ScrollableElementCreationOptions {
9
+ /**
10
+ * The scrollable element should not do any DOM mutations until renderNow() is called.
11
+ * Defaults to false.
12
+ */
13
+ lazyRender?: boolean;
14
+ /**
15
+ * CSS Class name for the scrollable element.
16
+ */
17
+ className?: string;
18
+ /**
19
+ * Drop subtle horizontal and vertical shadows.
20
+ * Defaults to false.
21
+ */
22
+ useShadows?: boolean;
23
+ /**
24
+ * Handle mouse wheel (listen to mouse wheel scrolling).
25
+ * Defaults to true
26
+ */
27
+ handleMouseWheel?: boolean;
28
+ /**
29
+ * If mouse wheel is handled, make mouse wheel scrolling smooth.
30
+ * Defaults to true.
31
+ */
32
+ mouseWheelSmoothScroll?: boolean;
33
+ /**
34
+ * Flip axes. Treat vertical scrolling like horizontal and vice-versa.
35
+ * Defaults to false.
36
+ */
37
+ flipAxes?: boolean;
38
+ /**
39
+ * If enabled, will scroll horizontally when scrolling vertical.
40
+ * Defaults to false.
41
+ */
42
+ scrollYToX?: boolean;
43
+ /**
44
+ * Consume all mouse wheel events if a scrollbar is needed (i.e. scrollSize > size).
45
+ * Defaults to false.
46
+ */
47
+ consumeMouseWheelIfScrollbarIsNeeded?: boolean;
48
+ /**
49
+ * Always consume mouse wheel events, even when scrolling is no longer possible.
50
+ * Defaults to false.
51
+ */
52
+ alwaysConsumeMouseWheel?: boolean;
53
+ /**
54
+ * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.
55
+ * Defaults to 1.
56
+ */
57
+ mouseWheelScrollSensitivity?: number;
58
+ /**
59
+ * FastScrolling mulitplier speed when pressing `Alt`
60
+ * Defaults to 5.
61
+ */
62
+ fastScrollSensitivity?: number;
63
+ /**
64
+ * Whether the scrollable will only scroll along the predominant axis when scrolling both
65
+ * vertically and horizontally at the same time.
66
+ * Prevents horizontal drift when scrolling vertically on a trackpad.
67
+ * Defaults to true.
68
+ */
69
+ scrollPredominantAxis?: boolean;
70
+ /**
71
+ * Height for vertical arrows (top/bottom) and width for horizontal arrows (left/right).
72
+ * Defaults to 11.
73
+ */
74
+ arrowSize?: number;
75
+ /**
76
+ * The dom node events should be bound to.
77
+ * If no listenOnDomNode is provided, the dom node passed to the constructor will be used for event listening.
78
+ */
79
+ listenOnDomNode?: HTMLElement;
80
+ /**
81
+ * Control the visibility of the horizontal scrollbar.
82
+ * Accepted values: 'auto' (on mouse over), 'visible' (always visible), 'hidden' (never visible)
83
+ * Defaults to 'auto'.
84
+ */
85
+ horizontal?: ScrollbarVisibility;
86
+ /**
87
+ * Height (in px) of the horizontal scrollbar.
88
+ * Defaults to 10.
89
+ */
90
+ horizontalScrollbarSize?: number;
91
+ /**
92
+ * Height (in px) of the horizontal scrollbar slider.
93
+ * Defaults to `horizontalScrollbarSize`
94
+ */
95
+ horizontalSliderSize?: number;
96
+ /**
97
+ * Render arrows (left/right) for the horizontal scrollbar.
98
+ * Defaults to false.
99
+ */
100
+ horizontalHasArrows?: boolean;
101
+ /**
102
+ * Control the visibility of the vertical scrollbar.
103
+ * Accepted values: 'auto' (on mouse over), 'visible' (always visible), 'hidden' (never visible)
104
+ * Defaults to 'auto'.
105
+ */
106
+ vertical?: ScrollbarVisibility;
107
+ /**
108
+ * Width (in px) of the vertical scrollbar.
109
+ * Defaults to 10.
110
+ */
111
+ verticalScrollbarSize?: number;
112
+ /**
113
+ * Width (in px) of the vertical scrollbar slider.
114
+ * Defaults to `verticalScrollbarSize`
115
+ */
116
+ verticalSliderSize?: number;
117
+ /**
118
+ * Render arrows (top/bottom) for the vertical scrollbar.
119
+ * Defaults to false.
120
+ */
121
+ verticalHasArrows?: boolean;
122
+ /**
123
+ * Scroll gutter clicks move by page vs. jump to position.
124
+ * Defaults to false.
125
+ */
126
+ scrollByPage?: boolean;
127
+ }
128
+
129
+ export interface ScrollableElementChangeOptions {
130
+ handleMouseWheel?: boolean;
131
+ mouseWheelScrollSensitivity?: number;
132
+ fastScrollSensitivity?: number;
133
+ scrollPredominantAxis?: boolean;
134
+ horizontal?: ScrollbarVisibility;
135
+ horizontalScrollbarSize?: number;
136
+ vertical?: ScrollbarVisibility;
137
+ verticalScrollbarSize?: number;
138
+ scrollByPage?: boolean;
139
+ }
140
+
141
+ export interface ScrollableElementResolvedOptions {
142
+ lazyRender: boolean;
143
+ className: string;
144
+ useShadows: boolean;
145
+ handleMouseWheel: boolean;
146
+ flipAxes: boolean;
147
+ scrollYToX: boolean;
148
+ consumeMouseWheelIfScrollbarIsNeeded: boolean;
149
+ alwaysConsumeMouseWheel: boolean;
150
+ mouseWheelScrollSensitivity: number;
151
+ fastScrollSensitivity: number;
152
+ scrollPredominantAxis: boolean;
153
+ mouseWheelSmoothScroll: boolean;
154
+ arrowSize: number;
155
+ listenOnDomNode: HTMLElement | null;
156
+ horizontal: ScrollbarVisibility;
157
+ horizontalScrollbarSize: number;
158
+ horizontalSliderSize: number;
159
+ horizontalHasArrows: boolean;
160
+ vertical: ScrollbarVisibility;
161
+ verticalScrollbarSize: number;
162
+ verticalSliderSize: number;
163
+ verticalHasArrows: boolean;
164
+ scrollByPage: boolean;
165
+ }
@@ -0,0 +1,114 @@
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 { GlobalPointerMoveMonitor } from 'vs/base/browser/globalPointerMoveMonitor';
7
+ import { Widget } from 'vs/base/browser/ui/widget';
8
+ import { TimeoutTimer } from 'vs/base/common/async';
9
+ import * as dom from 'vs/base/browser/dom';
10
+
11
+ /**
12
+ * The arrow image size.
13
+ */
14
+ export const ARROW_IMG_SIZE = 11;
15
+
16
+ export interface ScrollbarArrowOptions {
17
+ onActivate: () => void;
18
+ className: string;
19
+ // icon: ThemeIcon;
20
+
21
+ bgWidth: number;
22
+ bgHeight: number;
23
+
24
+ top?: number;
25
+ left?: number;
26
+ bottom?: number;
27
+ right?: number;
28
+ }
29
+
30
+ export class ScrollbarArrow extends Widget {
31
+
32
+ private _onActivate: () => void;
33
+ public bgDomNode: HTMLElement;
34
+ public domNode: HTMLElement;
35
+ private _pointerdownRepeatTimer: dom.WindowIntervalTimer;
36
+ private _pointerdownScheduleRepeatTimer: TimeoutTimer;
37
+ private _pointerMoveMonitor: GlobalPointerMoveMonitor;
38
+
39
+ constructor(opts: ScrollbarArrowOptions) {
40
+ super();
41
+ this._onActivate = opts.onActivate;
42
+
43
+ this.bgDomNode = document.createElement('div');
44
+ this.bgDomNode.className = 'arrow-background';
45
+ this.bgDomNode.style.position = 'absolute';
46
+ this.bgDomNode.style.width = opts.bgWidth + 'px';
47
+ this.bgDomNode.style.height = opts.bgHeight + 'px';
48
+ if (typeof opts.top !== 'undefined') {
49
+ this.bgDomNode.style.top = '0px';
50
+ }
51
+ if (typeof opts.left !== 'undefined') {
52
+ this.bgDomNode.style.left = '0px';
53
+ }
54
+ if (typeof opts.bottom !== 'undefined') {
55
+ this.bgDomNode.style.bottom = '0px';
56
+ }
57
+ if (typeof opts.right !== 'undefined') {
58
+ this.bgDomNode.style.right = '0px';
59
+ }
60
+
61
+ this.domNode = document.createElement('div');
62
+ this.domNode.className = opts.className;
63
+ // this.domNode.classList.add(...ThemeIcon.asClassNameArray(opts.icon));
64
+
65
+ this.domNode.style.position = 'absolute';
66
+ this.domNode.style.width = ARROW_IMG_SIZE + 'px';
67
+ this.domNode.style.height = ARROW_IMG_SIZE + 'px';
68
+ if (typeof opts.top !== 'undefined') {
69
+ this.domNode.style.top = opts.top + 'px';
70
+ }
71
+ if (typeof opts.left !== 'undefined') {
72
+ this.domNode.style.left = opts.left + 'px';
73
+ }
74
+ if (typeof opts.bottom !== 'undefined') {
75
+ this.domNode.style.bottom = opts.bottom + 'px';
76
+ }
77
+ if (typeof opts.right !== 'undefined') {
78
+ this.domNode.style.right = opts.right + 'px';
79
+ }
80
+
81
+ this._pointerMoveMonitor = this._register(new GlobalPointerMoveMonitor());
82
+ this._register(dom.addStandardDisposableListener(this.bgDomNode, dom.EventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));
83
+ this._register(dom.addStandardDisposableListener(this.domNode, dom.EventType.POINTER_DOWN, (e) => this._arrowPointerDown(e)));
84
+
85
+ this._pointerdownRepeatTimer = this._register(new dom.WindowIntervalTimer());
86
+ this._pointerdownScheduleRepeatTimer = this._register(new TimeoutTimer());
87
+ }
88
+
89
+ private _arrowPointerDown(e: PointerEvent): void {
90
+ if (!e.target || !(e.target instanceof Element)) {
91
+ return;
92
+ }
93
+ const scheduleRepeater = () => {
94
+ this._pointerdownRepeatTimer.cancelAndSet(() => this._onActivate(), 1000 / 24, dom.getWindow(e));
95
+ };
96
+
97
+ this._onActivate();
98
+ this._pointerdownRepeatTimer.cancel();
99
+ this._pointerdownScheduleRepeatTimer.cancelAndSet(scheduleRepeater, 200);
100
+
101
+ this._pointerMoveMonitor.startMonitoring(
102
+ e.target,
103
+ e.pointerId,
104
+ e.buttons,
105
+ (pointerMoveData) => { /* Intentional empty */ },
106
+ () => {
107
+ this._pointerdownRepeatTimer.cancel();
108
+ this._pointerdownScheduleRepeatTimer.cancel();
109
+ }
110
+ );
111
+
112
+ e.preventDefault();
113
+ }
114
+ }
@@ -0,0 +1,243 @@
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
+ /**
7
+ * The minimal size of the slider (such that it can still be clickable) -- it is artificially enlarged.
8
+ */
9
+ const MINIMUM_SLIDER_SIZE = 20;
10
+
11
+ export class ScrollbarState {
12
+
13
+ /**
14
+ * For the vertical scrollbar: the width.
15
+ * For the horizontal scrollbar: the height.
16
+ */
17
+ private _scrollbarSize: number;
18
+
19
+ /**
20
+ * For the vertical scrollbar: the height of the pair horizontal scrollbar.
21
+ * For the horizontal scrollbar: the width of the pair vertical scrollbar.
22
+ */
23
+ private _oppositeScrollbarSize: number;
24
+
25
+ /**
26
+ * For the vertical scrollbar: the height of the scrollbar's arrows.
27
+ * For the horizontal scrollbar: the width of the scrollbar's arrows.
28
+ */
29
+ private readonly _arrowSize: number;
30
+
31
+ // --- variables
32
+ /**
33
+ * For the vertical scrollbar: the viewport height.
34
+ * For the horizontal scrollbar: the viewport width.
35
+ */
36
+ private _visibleSize: number;
37
+
38
+ /**
39
+ * For the vertical scrollbar: the scroll height.
40
+ * For the horizontal scrollbar: the scroll width.
41
+ */
42
+ private _scrollSize: number;
43
+
44
+ /**
45
+ * For the vertical scrollbar: the scroll top.
46
+ * For the horizontal scrollbar: the scroll left.
47
+ */
48
+ private _scrollPosition: number;
49
+
50
+ // --- computed variables
51
+
52
+ /**
53
+ * `visibleSize` - `oppositeScrollbarSize`
54
+ */
55
+ private _computedAvailableSize: number;
56
+ /**
57
+ * (`scrollSize` > 0 && `scrollSize` > `visibleSize`)
58
+ */
59
+ private _computedIsNeeded: boolean;
60
+
61
+ private _computedSliderSize: number;
62
+ private _computedSliderRatio: number;
63
+ private _computedSliderPosition: number;
64
+
65
+ constructor(arrowSize: number, scrollbarSize: number, oppositeScrollbarSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {
66
+ this._scrollbarSize = Math.round(scrollbarSize);
67
+ this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);
68
+ this._arrowSize = Math.round(arrowSize);
69
+
70
+ this._visibleSize = visibleSize;
71
+ this._scrollSize = scrollSize;
72
+ this._scrollPosition = scrollPosition;
73
+
74
+ this._computedAvailableSize = 0;
75
+ this._computedIsNeeded = false;
76
+ this._computedSliderSize = 0;
77
+ this._computedSliderRatio = 0;
78
+ this._computedSliderPosition = 0;
79
+
80
+ this._refreshComputedValues();
81
+ }
82
+
83
+ public clone(): ScrollbarState {
84
+ return new ScrollbarState(this._arrowSize, this._scrollbarSize, this._oppositeScrollbarSize, this._visibleSize, this._scrollSize, this._scrollPosition);
85
+ }
86
+
87
+ public setVisibleSize(visibleSize: number): boolean {
88
+ const iVisibleSize = Math.round(visibleSize);
89
+ if (this._visibleSize !== iVisibleSize) {
90
+ this._visibleSize = iVisibleSize;
91
+ this._refreshComputedValues();
92
+ return true;
93
+ }
94
+ return false;
95
+ }
96
+
97
+ public setScrollSize(scrollSize: number): boolean {
98
+ const iScrollSize = Math.round(scrollSize);
99
+ if (this._scrollSize !== iScrollSize) {
100
+ this._scrollSize = iScrollSize;
101
+ this._refreshComputedValues();
102
+ return true;
103
+ }
104
+ return false;
105
+ }
106
+
107
+ public setScrollPosition(scrollPosition: number): boolean {
108
+ const iScrollPosition = Math.round(scrollPosition);
109
+ if (this._scrollPosition !== iScrollPosition) {
110
+ this._scrollPosition = iScrollPosition;
111
+ this._refreshComputedValues();
112
+ return true;
113
+ }
114
+ return false;
115
+ }
116
+
117
+ public setScrollbarSize(scrollbarSize: number): void {
118
+ this._scrollbarSize = Math.round(scrollbarSize);
119
+ }
120
+
121
+ public setOppositeScrollbarSize(oppositeScrollbarSize: number): void {
122
+ this._oppositeScrollbarSize = Math.round(oppositeScrollbarSize);
123
+ }
124
+
125
+ private static _computeValues(oppositeScrollbarSize: number, arrowSize: number, visibleSize: number, scrollSize: number, scrollPosition: number) {
126
+ const computedAvailableSize = Math.max(0, visibleSize - oppositeScrollbarSize);
127
+ const computedRepresentableSize = Math.max(0, computedAvailableSize - 2 * arrowSize);
128
+ const computedIsNeeded = (scrollSize > 0 && scrollSize > visibleSize);
129
+
130
+ if (!computedIsNeeded) {
131
+ // There is no need for a slider
132
+ return {
133
+ computedAvailableSize: Math.round(computedAvailableSize),
134
+ computedIsNeeded: computedIsNeeded,
135
+ computedSliderSize: Math.round(computedRepresentableSize),
136
+ computedSliderRatio: 0,
137
+ computedSliderPosition: 0,
138
+ };
139
+ }
140
+
141
+ // We must artificially increase the size of the slider if needed, since the slider would be too small to grab with the mouse otherwise
142
+ const computedSliderSize = Math.round(Math.max(MINIMUM_SLIDER_SIZE, Math.floor(visibleSize * computedRepresentableSize / scrollSize)));
143
+
144
+ // The slider can move from 0 to `computedRepresentableSize` - `computedSliderSize`
145
+ // in the same way `scrollPosition` can move from 0 to `scrollSize` - `visibleSize`.
146
+ const computedSliderRatio = (computedRepresentableSize - computedSliderSize) / (scrollSize - visibleSize);
147
+ const computedSliderPosition = (scrollPosition * computedSliderRatio);
148
+
149
+ return {
150
+ computedAvailableSize: Math.round(computedAvailableSize),
151
+ computedIsNeeded: computedIsNeeded,
152
+ computedSliderSize: Math.round(computedSliderSize),
153
+ computedSliderRatio: computedSliderRatio,
154
+ computedSliderPosition: Math.round(computedSliderPosition),
155
+ };
156
+ }
157
+
158
+ private _refreshComputedValues(): void {
159
+ const r = ScrollbarState._computeValues(this._oppositeScrollbarSize, this._arrowSize, this._visibleSize, this._scrollSize, this._scrollPosition);
160
+ this._computedAvailableSize = r.computedAvailableSize;
161
+ this._computedIsNeeded = r.computedIsNeeded;
162
+ this._computedSliderSize = r.computedSliderSize;
163
+ this._computedSliderRatio = r.computedSliderRatio;
164
+ this._computedSliderPosition = r.computedSliderPosition;
165
+ }
166
+
167
+ public getArrowSize(): number {
168
+ return this._arrowSize;
169
+ }
170
+
171
+ public getScrollPosition(): number {
172
+ return this._scrollPosition;
173
+ }
174
+
175
+ public getRectangleLargeSize(): number {
176
+ return this._computedAvailableSize;
177
+ }
178
+
179
+ public getRectangleSmallSize(): number {
180
+ return this._scrollbarSize;
181
+ }
182
+
183
+ public isNeeded(): boolean {
184
+ return this._computedIsNeeded;
185
+ }
186
+
187
+ public getSliderSize(): number {
188
+ return this._computedSliderSize;
189
+ }
190
+
191
+ public getSliderPosition(): number {
192
+ return this._computedSliderPosition;
193
+ }
194
+
195
+ /**
196
+ * Compute a desired `scrollPosition` such that `offset` ends up in the center of the slider.
197
+ * `offset` is based on the same coordinate system as the `sliderPosition`.
198
+ */
199
+ public getDesiredScrollPositionFromOffset(offset: number): number {
200
+ if (!this._computedIsNeeded) {
201
+ // no need for a slider
202
+ return 0;
203
+ }
204
+
205
+ const desiredSliderPosition = offset - this._arrowSize - this._computedSliderSize / 2;
206
+ return Math.round(desiredSliderPosition / this._computedSliderRatio);
207
+ }
208
+
209
+ /**
210
+ * Compute a desired `scrollPosition` from if offset is before or after the slider position.
211
+ * If offset is before slider, treat as a page up (or left). If after, page down (or right).
212
+ * `offset` and `_computedSliderPosition` are based on the same coordinate system.
213
+ * `_visibleSize` corresponds to a "page" of lines in the returned coordinate system.
214
+ */
215
+ public getDesiredScrollPositionFromOffsetPaged(offset: number): number {
216
+ if (!this._computedIsNeeded) {
217
+ // no need for a slider
218
+ return 0;
219
+ }
220
+
221
+ const correctedOffset = offset - this._arrowSize; // compensate if has arrows
222
+ let desiredScrollPosition = this._scrollPosition;
223
+ if (correctedOffset < this._computedSliderPosition) {
224
+ desiredScrollPosition -= this._visibleSize; // page up/left
225
+ } else {
226
+ desiredScrollPosition += this._visibleSize; // page down/right
227
+ }
228
+ return desiredScrollPosition;
229
+ }
230
+
231
+ /**
232
+ * Compute a desired `scrollPosition` such that the slider moves by `delta`.
233
+ */
234
+ public getDesiredScrollPositionFromDelta(delta: number): number {
235
+ if (!this._computedIsNeeded) {
236
+ // no need for a slider
237
+ return 0;
238
+ }
239
+
240
+ const desiredSliderPosition = this._computedSliderPosition + delta;
241
+ return Math.round(desiredSliderPosition / this._computedSliderRatio);
242
+ }
243
+ }
@@ -0,0 +1,118 @@
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 { FastDomNode } from 'vs/base/browser/fastDomNode';
7
+ import { TimeoutTimer } from 'vs/base/common/async';
8
+ import { Disposable } from 'vs/base/common/lifecycle';
9
+ import { ScrollbarVisibility } from 'vs/base/common/scrollable';
10
+
11
+ export class ScrollbarVisibilityController extends Disposable {
12
+ private _visibility: ScrollbarVisibility;
13
+ private _visibleClassName: string;
14
+ private _invisibleClassName: string;
15
+ private _domNode: FastDomNode<HTMLElement> | null;
16
+ private _rawShouldBeVisible: boolean;
17
+ private _shouldBeVisible: boolean;
18
+ private _isNeeded: boolean;
19
+ private _isVisible: boolean;
20
+ private _revealTimer: TimeoutTimer;
21
+
22
+ constructor(visibility: ScrollbarVisibility, visibleClassName: string, invisibleClassName: string) {
23
+ super();
24
+ this._visibility = visibility;
25
+ this._visibleClassName = visibleClassName;
26
+ this._invisibleClassName = invisibleClassName;
27
+ this._domNode = null;
28
+ this._isVisible = false;
29
+ this._isNeeded = false;
30
+ this._rawShouldBeVisible = false;
31
+ this._shouldBeVisible = false;
32
+ this._revealTimer = this._register(new TimeoutTimer());
33
+ }
34
+
35
+ public setVisibility(visibility: ScrollbarVisibility): void {
36
+ if (this._visibility !== visibility) {
37
+ this._visibility = visibility;
38
+ this._updateShouldBeVisible();
39
+ }
40
+ }
41
+
42
+ // ----------------- Hide / Reveal
43
+
44
+ public setShouldBeVisible(rawShouldBeVisible: boolean): void {
45
+ this._rawShouldBeVisible = rawShouldBeVisible;
46
+ this._updateShouldBeVisible();
47
+ }
48
+
49
+ private _applyVisibilitySetting(): boolean {
50
+ if (this._visibility === ScrollbarVisibility.Hidden) {
51
+ return false;
52
+ }
53
+ if (this._visibility === ScrollbarVisibility.Visible) {
54
+ return true;
55
+ }
56
+ return this._rawShouldBeVisible;
57
+ }
58
+
59
+ private _updateShouldBeVisible(): void {
60
+ const shouldBeVisible = this._applyVisibilitySetting();
61
+
62
+ if (this._shouldBeVisible !== shouldBeVisible) {
63
+ this._shouldBeVisible = shouldBeVisible;
64
+ this.ensureVisibility();
65
+ }
66
+ }
67
+
68
+ public setIsNeeded(isNeeded: boolean): void {
69
+ if (this._isNeeded !== isNeeded) {
70
+ this._isNeeded = isNeeded;
71
+ this.ensureVisibility();
72
+ }
73
+ }
74
+
75
+ public setDomNode(domNode: FastDomNode<HTMLElement>): void {
76
+ this._domNode = domNode;
77
+ this._domNode.setClassName(this._invisibleClassName);
78
+
79
+ // Now that the flags & the dom node are in a consistent state, ensure the Hidden/Visible configuration
80
+ this.setShouldBeVisible(false);
81
+ }
82
+
83
+ public ensureVisibility(): void {
84
+
85
+ if (!this._isNeeded) {
86
+ // Nothing to be rendered
87
+ this._hide(false);
88
+ return;
89
+ }
90
+
91
+ if (this._shouldBeVisible) {
92
+ this._reveal();
93
+ } else {
94
+ this._hide(true);
95
+ }
96
+ }
97
+
98
+ private _reveal(): void {
99
+ if (this._isVisible) {
100
+ return;
101
+ }
102
+ this._isVisible = true;
103
+
104
+ // The CSS animation doesn't play otherwise
105
+ this._revealTimer.setIfNotSet(() => {
106
+ this._domNode?.setClassName(this._visibleClassName);
107
+ }, 0);
108
+ }
109
+
110
+ private _hide(withFadeAway: boolean): void {
111
+ this._revealTimer.cancel();
112
+ if (!this._isVisible) {
113
+ return;
114
+ }
115
+ this._isVisible = false;
116
+ this._domNode?.setClassName(this._invisibleClassName + (withFadeAway ? ' fade' : ''));
117
+ }
118
+ }