@xterm/xterm 5.6.0-beta.7 → 5.6.0-beta.71
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.
- package/README.md +6 -3
- package/css/xterm.css +71 -4
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +53 -0
- package/lib/xterm.mjs.map +7 -0
- package/package.json +43 -33
- package/src/browser/AccessibilityManager.ts +53 -25
- package/src/browser/{Terminal.ts → CoreBrowserTerminal.ts} +135 -146
- package/src/browser/Linkifier.ts +26 -14
- package/src/browser/LocalizableStrings.ts +15 -4
- package/src/browser/{Types.d.ts → Types.ts} +67 -15
- package/src/browser/Viewport.ts +143 -370
- package/src/browser/decorations/BufferDecorationRenderer.ts +14 -9
- package/src/browser/decorations/OverviewRulerRenderer.ts +40 -44
- package/src/browser/public/Terminal.ts +25 -19
- package/src/browser/renderer/dom/DomRenderer.ts +14 -16
- package/src/browser/renderer/shared/CharAtlasUtils.ts +4 -0
- package/src/browser/renderer/shared/CustomGlyphs.ts +6 -0
- package/src/browser/renderer/shared/DevicePixelObserver.ts +1 -2
- package/src/browser/renderer/shared/TextureAtlas.ts +3 -3
- package/src/browser/renderer/shared/{Types.d.ts → Types.ts} +4 -4
- package/src/browser/services/CharSizeService.ts +6 -6
- package/src/browser/services/CoreBrowserService.ts +15 -15
- package/src/browser/services/LinkProviderService.ts +2 -2
- package/src/browser/services/RenderService.ts +20 -20
- package/src/browser/services/SelectionService.ts +8 -8
- package/src/browser/services/Services.ts +13 -13
- package/src/browser/services/ThemeService.ts +18 -57
- package/src/browser/shared/Constants.ts +8 -0
- package/src/common/CircularList.ts +5 -5
- package/src/common/CoreTerminal.ts +35 -41
- package/src/common/InputHandler.ts +34 -28
- package/src/common/{Types.d.ts → Types.ts} +11 -17
- package/src/common/buffer/Buffer.ts +15 -7
- package/src/common/buffer/BufferReflow.ts +9 -6
- package/src/common/buffer/BufferSet.ts +5 -5
- package/src/common/buffer/Marker.ts +4 -4
- package/src/common/buffer/{Types.d.ts → Types.ts} +2 -2
- package/src/common/input/WriteBuffer.ts +3 -3
- package/src/common/parser/EscapeSequenceParser.ts +4 -4
- package/src/common/public/BufferNamespaceApi.ts +3 -3
- package/src/common/services/BufferService.ts +7 -7
- package/src/common/services/CoreMouseService.ts +5 -3
- package/src/common/services/CoreService.ts +6 -6
- package/src/common/services/DecorationService.ts +8 -9
- package/src/common/services/LogService.ts +2 -2
- package/src/common/services/OptionsService.ts +6 -5
- package/src/common/services/Services.ts +25 -17
- package/src/common/services/UnicodeService.ts +2 -2
- package/src/vs/base/browser/browser.ts +141 -0
- package/src/vs/base/browser/canIUse.ts +49 -0
- package/src/vs/base/browser/dom.ts +2369 -0
- package/src/vs/base/browser/fastDomNode.ts +316 -0
- package/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
- package/src/vs/base/browser/iframe.ts +135 -0
- package/src/vs/base/browser/keyboardEvent.ts +213 -0
- package/src/vs/base/browser/mouseEvent.ts +229 -0
- package/src/vs/base/browser/touch.ts +372 -0
- package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
- package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
- package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
- package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
- package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
- package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
- package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
- package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
- package/src/vs/base/browser/ui/widget.ts +57 -0
- package/src/vs/base/browser/window.ts +14 -0
- package/src/vs/base/common/arrays.ts +887 -0
- package/src/vs/base/common/arraysFind.ts +202 -0
- package/src/vs/base/common/assert.ts +71 -0
- package/src/vs/base/common/async.ts +1992 -0
- package/src/vs/base/common/cancellation.ts +148 -0
- package/src/vs/base/common/charCode.ts +450 -0
- package/src/vs/base/common/collections.ts +140 -0
- package/src/vs/base/common/decorators.ts +130 -0
- package/src/vs/base/common/equals.ts +146 -0
- package/src/vs/base/common/errors.ts +303 -0
- package/src/vs/base/common/event.ts +1778 -0
- package/src/vs/base/common/functional.ts +32 -0
- package/src/vs/base/common/hash.ts +316 -0
- package/src/vs/base/common/iterator.ts +159 -0
- package/src/vs/base/common/keyCodes.ts +526 -0
- package/src/vs/base/common/keybindings.ts +284 -0
- package/src/vs/base/common/lazy.ts +47 -0
- package/src/vs/base/common/lifecycle.ts +801 -0
- package/src/vs/base/common/linkedList.ts +142 -0
- package/src/vs/base/common/map.ts +202 -0
- package/src/vs/base/common/numbers.ts +98 -0
- package/src/vs/base/common/observable.ts +76 -0
- package/src/vs/base/common/observableInternal/api.ts +31 -0
- package/src/vs/base/common/observableInternal/autorun.ts +281 -0
- package/src/vs/base/common/observableInternal/base.ts +489 -0
- package/src/vs/base/common/observableInternal/debugName.ts +145 -0
- package/src/vs/base/common/observableInternal/derived.ts +428 -0
- package/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
- package/src/vs/base/common/observableInternal/logging.ts +328 -0
- package/src/vs/base/common/observableInternal/promise.ts +209 -0
- package/src/vs/base/common/observableInternal/utils.ts +610 -0
- package/src/vs/base/common/platform.ts +281 -0
- package/src/vs/base/common/scrollable.ts +522 -0
- package/src/vs/base/common/sequence.ts +34 -0
- package/src/vs/base/common/stopwatch.ts +43 -0
- package/src/vs/base/common/strings.ts +557 -0
- package/src/vs/base/common/symbols.ts +9 -0
- package/src/vs/base/common/uint.ts +59 -0
- package/src/vs/patches/nls.ts +90 -0
- package/src/vs/typings/base-common.d.ts +20 -0
- package/src/vs/typings/require.d.ts +42 -0
- package/src/vs/typings/thenable.d.ts +12 -0
- package/src/vs/typings/vscode-globals-nls.d.ts +36 -0
- package/src/vs/typings/vscode-globals-product.d.ts +33 -0
- package/typings/xterm.d.ts +66 -15
- package/src/browser/Lifecycle.ts +0 -33
- package/src/common/EventEmitter.ts +0 -78
- package/src/common/Lifecycle.ts +0 -108
- /package/src/browser/selection/{Types.d.ts → Types.ts} +0 -0
- /package/src/common/parser/{Types.d.ts → Types.ts} +0 -0
|
@@ -0,0 +1,720 @@
|
|
|
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 { getZoomFactor, isChrome } from 'vs/base/browser/browser';
|
|
7
|
+
import * as dom from 'vs/base/browser/dom';
|
|
8
|
+
import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode';
|
|
9
|
+
import { IMouseEvent, IMouseWheelEvent, StandardWheelEvent } from 'vs/base/browser/mouseEvent';
|
|
10
|
+
import { ScrollbarHost } from 'vs/base/browser/ui/scrollbar/abstractScrollbar';
|
|
11
|
+
import { HorizontalScrollbar } from 'vs/base/browser/ui/scrollbar/horizontalScrollbar';
|
|
12
|
+
import { ScrollableElementChangeOptions, ScrollableElementCreationOptions, ScrollableElementResolvedOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
|
|
13
|
+
import { VerticalScrollbar } from 'vs/base/browser/ui/scrollbar/verticalScrollbar';
|
|
14
|
+
import { Widget } from 'vs/base/browser/ui/widget';
|
|
15
|
+
import { TimeoutTimer } from 'vs/base/common/async';
|
|
16
|
+
import { Emitter, Event } from 'vs/base/common/event';
|
|
17
|
+
import { IDisposable, dispose } from 'vs/base/common/lifecycle';
|
|
18
|
+
import * as platform from 'vs/base/common/platform';
|
|
19
|
+
import { INewScrollDimensions, INewScrollPosition, IScrollDimensions, IScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable';
|
|
20
|
+
// import 'vs/css!./media/scrollbars';
|
|
21
|
+
|
|
22
|
+
const HIDE_TIMEOUT = 500;
|
|
23
|
+
const SCROLL_WHEEL_SENSITIVITY = 50;
|
|
24
|
+
const SCROLL_WHEEL_SMOOTH_SCROLL_ENABLED = true;
|
|
25
|
+
|
|
26
|
+
export interface IOverviewRulerLayoutInfo {
|
|
27
|
+
parent: HTMLElement;
|
|
28
|
+
insertBefore: HTMLElement;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
class MouseWheelClassifierItem {
|
|
32
|
+
public timestamp: number;
|
|
33
|
+
public deltaX: number;
|
|
34
|
+
public deltaY: number;
|
|
35
|
+
public score: number;
|
|
36
|
+
|
|
37
|
+
constructor(timestamp: number, deltaX: number, deltaY: number) {
|
|
38
|
+
this.timestamp = timestamp;
|
|
39
|
+
this.deltaX = deltaX;
|
|
40
|
+
this.deltaY = deltaY;
|
|
41
|
+
this.score = 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export class MouseWheelClassifier {
|
|
46
|
+
|
|
47
|
+
public static readonly INSTANCE = new MouseWheelClassifier();
|
|
48
|
+
|
|
49
|
+
private readonly _capacity: number;
|
|
50
|
+
private _memory: MouseWheelClassifierItem[];
|
|
51
|
+
private _front: number;
|
|
52
|
+
private _rear: number;
|
|
53
|
+
|
|
54
|
+
constructor() {
|
|
55
|
+
this._capacity = 5;
|
|
56
|
+
this._memory = [];
|
|
57
|
+
this._front = -1;
|
|
58
|
+
this._rear = -1;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
public isPhysicalMouseWheel(): boolean {
|
|
62
|
+
if (this._front === -1 && this._rear === -1) {
|
|
63
|
+
// no elements
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// 0.5 * last + 0.25 * 2nd last + 0.125 * 3rd last + ...
|
|
68
|
+
let remainingInfluence = 1;
|
|
69
|
+
let score = 0;
|
|
70
|
+
let iteration = 1;
|
|
71
|
+
|
|
72
|
+
let index = this._rear;
|
|
73
|
+
do {
|
|
74
|
+
const influence = (index === this._front ? remainingInfluence : Math.pow(2, -iteration));
|
|
75
|
+
remainingInfluence -= influence;
|
|
76
|
+
score += this._memory[index].score * influence;
|
|
77
|
+
|
|
78
|
+
if (index === this._front) {
|
|
79
|
+
break;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
index = (this._capacity + index - 1) % this._capacity;
|
|
83
|
+
iteration++;
|
|
84
|
+
} while (true);
|
|
85
|
+
|
|
86
|
+
return (score <= 0.5);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
public acceptStandardWheelEvent(e: StandardWheelEvent): void {
|
|
90
|
+
if (isChrome) {
|
|
91
|
+
const targetWindow = dom.getWindow(e.browserEvent);
|
|
92
|
+
const pageZoomFactor = getZoomFactor(targetWindow);
|
|
93
|
+
// On Chrome, the incoming delta events are multiplied with the OS zoom factor.
|
|
94
|
+
// The OS zoom factor can be reverse engineered by using the device pixel ratio and the configured zoom factor into account.
|
|
95
|
+
this.accept(Date.now(), e.deltaX * pageZoomFactor, e.deltaY * pageZoomFactor);
|
|
96
|
+
} else {
|
|
97
|
+
this.accept(Date.now(), e.deltaX, e.deltaY);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
public accept(timestamp: number, deltaX: number, deltaY: number): void {
|
|
102
|
+
let previousItem = null;
|
|
103
|
+
const item = new MouseWheelClassifierItem(timestamp, deltaX, deltaY);
|
|
104
|
+
|
|
105
|
+
if (this._front === -1 && this._rear === -1) {
|
|
106
|
+
this._memory[0] = item;
|
|
107
|
+
this._front = 0;
|
|
108
|
+
this._rear = 0;
|
|
109
|
+
} else {
|
|
110
|
+
previousItem = this._memory[this._rear];
|
|
111
|
+
|
|
112
|
+
this._rear = (this._rear + 1) % this._capacity;
|
|
113
|
+
if (this._rear === this._front) {
|
|
114
|
+
// Drop oldest
|
|
115
|
+
this._front = (this._front + 1) % this._capacity;
|
|
116
|
+
}
|
|
117
|
+
this._memory[this._rear] = item;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
item.score = this._computeScore(item, previousItem);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* A score between 0 and 1 for `item`.
|
|
125
|
+
* - a score towards 0 indicates that the source appears to be a physical mouse wheel
|
|
126
|
+
* - a score towards 1 indicates that the source appears to be a touchpad or magic mouse, etc.
|
|
127
|
+
*/
|
|
128
|
+
private _computeScore(item: MouseWheelClassifierItem, previousItem: MouseWheelClassifierItem | null): number {
|
|
129
|
+
|
|
130
|
+
if (Math.abs(item.deltaX) > 0 && Math.abs(item.deltaY) > 0) {
|
|
131
|
+
// both axes exercised => definitely not a physical mouse wheel
|
|
132
|
+
return 1;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
let score: number = 0.5;
|
|
136
|
+
|
|
137
|
+
if (!this._isAlmostInt(item.deltaX) || !this._isAlmostInt(item.deltaY)) {
|
|
138
|
+
// non-integer deltas => indicator that this is not a physical mouse wheel
|
|
139
|
+
score += 0.25;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Non-accelerating scroll => indicator that this is a physical mouse wheel
|
|
143
|
+
// These can be identified by seeing whether they are the module of one another.
|
|
144
|
+
if (previousItem) {
|
|
145
|
+
const absDeltaX = Math.abs(item.deltaX);
|
|
146
|
+
const absDeltaY = Math.abs(item.deltaY);
|
|
147
|
+
|
|
148
|
+
const absPreviousDeltaX = Math.abs(previousItem.deltaX);
|
|
149
|
+
const absPreviousDeltaY = Math.abs(previousItem.deltaY);
|
|
150
|
+
|
|
151
|
+
// Min 1 to avoid division by zero, module 1 will still be 0.
|
|
152
|
+
const minDeltaX = Math.max(Math.min(absDeltaX, absPreviousDeltaX), 1);
|
|
153
|
+
const minDeltaY = Math.max(Math.min(absDeltaY, absPreviousDeltaY), 1);
|
|
154
|
+
|
|
155
|
+
const maxDeltaX = Math.max(absDeltaX, absPreviousDeltaX);
|
|
156
|
+
const maxDeltaY = Math.max(absDeltaY, absPreviousDeltaY);
|
|
157
|
+
|
|
158
|
+
const isSameModulo = (maxDeltaX % minDeltaX === 0 && maxDeltaY % minDeltaY === 0);
|
|
159
|
+
if (isSameModulo) {
|
|
160
|
+
score -= 0.5;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return Math.min(Math.max(score, 0), 1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private _isAlmostInt(value: number): boolean {
|
|
168
|
+
const delta = Math.abs(Math.round(value) - value);
|
|
169
|
+
return (delta < 0.01);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export abstract class AbstractScrollableElement extends Widget {
|
|
174
|
+
|
|
175
|
+
private readonly _options: ScrollableElementResolvedOptions;
|
|
176
|
+
protected readonly _scrollable: Scrollable;
|
|
177
|
+
private readonly _verticalScrollbar: VerticalScrollbar;
|
|
178
|
+
private readonly _horizontalScrollbar: HorizontalScrollbar;
|
|
179
|
+
private readonly _domNode: HTMLElement;
|
|
180
|
+
|
|
181
|
+
private readonly _leftShadowDomNode: FastDomNode<HTMLElement> | null;
|
|
182
|
+
private readonly _topShadowDomNode: FastDomNode<HTMLElement> | null;
|
|
183
|
+
private readonly _topLeftShadowDomNode: FastDomNode<HTMLElement> | null;
|
|
184
|
+
|
|
185
|
+
private readonly _listenOnDomNode: HTMLElement;
|
|
186
|
+
|
|
187
|
+
private _mouseWheelToDispose: IDisposable[];
|
|
188
|
+
|
|
189
|
+
private _isDragging: boolean;
|
|
190
|
+
private _mouseIsOver: boolean;
|
|
191
|
+
|
|
192
|
+
private readonly _hideTimeout: TimeoutTimer;
|
|
193
|
+
private _shouldRender: boolean;
|
|
194
|
+
|
|
195
|
+
private _revealOnScroll: boolean;
|
|
196
|
+
|
|
197
|
+
private readonly _onScroll = this._register(new Emitter<ScrollEvent>());
|
|
198
|
+
public readonly onScroll: Event<ScrollEvent> = this._onScroll.event;
|
|
199
|
+
|
|
200
|
+
private readonly _onWillScroll = this._register(new Emitter<ScrollEvent>());
|
|
201
|
+
public readonly onWillScroll: Event<ScrollEvent> = this._onWillScroll.event;
|
|
202
|
+
|
|
203
|
+
public get options(): Readonly<ScrollableElementResolvedOptions> {
|
|
204
|
+
return this._options;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
protected constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable: Scrollable) {
|
|
208
|
+
super();
|
|
209
|
+
// HACK: xterm.js currnetly requires overflow to allow decorations to escape the container
|
|
210
|
+
// element.style.overflow = 'hidden';
|
|
211
|
+
this._options = resolveOptions(options);
|
|
212
|
+
this._scrollable = scrollable;
|
|
213
|
+
|
|
214
|
+
this._register(this._scrollable.onScroll((e) => {
|
|
215
|
+
this._onWillScroll.fire(e);
|
|
216
|
+
this._onDidScroll(e);
|
|
217
|
+
this._onScroll.fire(e);
|
|
218
|
+
}));
|
|
219
|
+
|
|
220
|
+
const scrollbarHost: ScrollbarHost = {
|
|
221
|
+
onMouseWheel: (mouseWheelEvent: StandardWheelEvent) => this._onMouseWheel(mouseWheelEvent),
|
|
222
|
+
onDragStart: () => this._onDragStart(),
|
|
223
|
+
onDragEnd: () => this._onDragEnd(),
|
|
224
|
+
};
|
|
225
|
+
this._verticalScrollbar = this._register(new VerticalScrollbar(this._scrollable, this._options, scrollbarHost));
|
|
226
|
+
this._horizontalScrollbar = this._register(new HorizontalScrollbar(this._scrollable, this._options, scrollbarHost));
|
|
227
|
+
|
|
228
|
+
this._domNode = document.createElement('div');
|
|
229
|
+
this._domNode.className = 'xterm-scrollable-element ' + this._options.className;
|
|
230
|
+
this._domNode.setAttribute('role', 'presentation');
|
|
231
|
+
this._domNode.style.position = 'relative';
|
|
232
|
+
// HACK: xterm.js currnetly requires overflow to allow decorations to escape the container
|
|
233
|
+
// this._domNode.style.overflow = 'hidden';
|
|
234
|
+
this._domNode.appendChild(element);
|
|
235
|
+
this._domNode.appendChild(this._horizontalScrollbar.domNode.domNode);
|
|
236
|
+
this._domNode.appendChild(this._verticalScrollbar.domNode.domNode);
|
|
237
|
+
|
|
238
|
+
if (this._options.useShadows) {
|
|
239
|
+
this._leftShadowDomNode = createFastDomNode(document.createElement('div'));
|
|
240
|
+
this._leftShadowDomNode.setClassName('shadow');
|
|
241
|
+
this._domNode.appendChild(this._leftShadowDomNode.domNode);
|
|
242
|
+
|
|
243
|
+
this._topShadowDomNode = createFastDomNode(document.createElement('div'));
|
|
244
|
+
this._topShadowDomNode.setClassName('shadow');
|
|
245
|
+
this._domNode.appendChild(this._topShadowDomNode.domNode);
|
|
246
|
+
|
|
247
|
+
this._topLeftShadowDomNode = createFastDomNode(document.createElement('div'));
|
|
248
|
+
this._topLeftShadowDomNode.setClassName('shadow');
|
|
249
|
+
this._domNode.appendChild(this._topLeftShadowDomNode.domNode);
|
|
250
|
+
} else {
|
|
251
|
+
this._leftShadowDomNode = null;
|
|
252
|
+
this._topShadowDomNode = null;
|
|
253
|
+
this._topLeftShadowDomNode = null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
this._listenOnDomNode = this._options.listenOnDomNode || this._domNode;
|
|
257
|
+
|
|
258
|
+
this._mouseWheelToDispose = [];
|
|
259
|
+
this._setListeningToMouseWheel(this._options.handleMouseWheel);
|
|
260
|
+
|
|
261
|
+
this.onmouseover(this._listenOnDomNode, (e) => this._onMouseOver(e));
|
|
262
|
+
this.onmouseleave(this._listenOnDomNode, (e) => this._onMouseLeave(e));
|
|
263
|
+
|
|
264
|
+
this._hideTimeout = this._register(new TimeoutTimer());
|
|
265
|
+
this._isDragging = false;
|
|
266
|
+
this._mouseIsOver = false;
|
|
267
|
+
|
|
268
|
+
this._shouldRender = true;
|
|
269
|
+
|
|
270
|
+
this._revealOnScroll = true;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
public override dispose(): void {
|
|
274
|
+
this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);
|
|
275
|
+
super.dispose();
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Get the generated 'scrollable' dom node
|
|
280
|
+
*/
|
|
281
|
+
public getDomNode(): HTMLElement {
|
|
282
|
+
return this._domNode;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
public getOverviewRulerLayoutInfo(): IOverviewRulerLayoutInfo {
|
|
286
|
+
return {
|
|
287
|
+
parent: this._domNode,
|
|
288
|
+
insertBefore: this._verticalScrollbar.domNode.domNode,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Delegate a pointer down event to the vertical scrollbar.
|
|
294
|
+
* This is to help with clicking somewhere else and having the scrollbar react.
|
|
295
|
+
*/
|
|
296
|
+
public delegateVerticalScrollbarPointerDown(browserEvent: PointerEvent): void {
|
|
297
|
+
this._verticalScrollbar.delegatePointerDown(browserEvent);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
public getScrollDimensions(): IScrollDimensions {
|
|
301
|
+
return this._scrollable.getScrollDimensions();
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
public setScrollDimensions(dimensions: INewScrollDimensions): void {
|
|
305
|
+
this._scrollable.setScrollDimensions(dimensions, false);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Update the class name of the scrollable element.
|
|
310
|
+
*/
|
|
311
|
+
public updateClassName(newClassName: string): void {
|
|
312
|
+
this._options.className = newClassName;
|
|
313
|
+
// Defaults are different on Macs
|
|
314
|
+
if (platform.isMacintosh) {
|
|
315
|
+
this._options.className += ' mac';
|
|
316
|
+
}
|
|
317
|
+
this._domNode.className = 'xterm-scrollable-element ' + this._options.className;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Update configuration options for the scrollbar.
|
|
322
|
+
*/
|
|
323
|
+
public updateOptions(newOptions: ScrollableElementChangeOptions): void {
|
|
324
|
+
if (typeof newOptions.handleMouseWheel !== 'undefined') {
|
|
325
|
+
this._options.handleMouseWheel = newOptions.handleMouseWheel;
|
|
326
|
+
this._setListeningToMouseWheel(this._options.handleMouseWheel);
|
|
327
|
+
}
|
|
328
|
+
if (typeof newOptions.mouseWheelScrollSensitivity !== 'undefined') {
|
|
329
|
+
this._options.mouseWheelScrollSensitivity = newOptions.mouseWheelScrollSensitivity;
|
|
330
|
+
}
|
|
331
|
+
if (typeof newOptions.fastScrollSensitivity !== 'undefined') {
|
|
332
|
+
this._options.fastScrollSensitivity = newOptions.fastScrollSensitivity;
|
|
333
|
+
}
|
|
334
|
+
if (typeof newOptions.scrollPredominantAxis !== 'undefined') {
|
|
335
|
+
this._options.scrollPredominantAxis = newOptions.scrollPredominantAxis;
|
|
336
|
+
}
|
|
337
|
+
if (typeof newOptions.horizontal !== 'undefined') {
|
|
338
|
+
this._options.horizontal = newOptions.horizontal;
|
|
339
|
+
}
|
|
340
|
+
if (typeof newOptions.vertical !== 'undefined') {
|
|
341
|
+
this._options.vertical = newOptions.vertical;
|
|
342
|
+
}
|
|
343
|
+
if (typeof newOptions.horizontalScrollbarSize !== 'undefined') {
|
|
344
|
+
this._options.horizontalScrollbarSize = newOptions.horizontalScrollbarSize;
|
|
345
|
+
}
|
|
346
|
+
if (typeof newOptions.verticalScrollbarSize !== 'undefined') {
|
|
347
|
+
this._options.verticalScrollbarSize = newOptions.verticalScrollbarSize;
|
|
348
|
+
}
|
|
349
|
+
if (typeof newOptions.scrollByPage !== 'undefined') {
|
|
350
|
+
this._options.scrollByPage = newOptions.scrollByPage;
|
|
351
|
+
}
|
|
352
|
+
this._horizontalScrollbar.updateOptions(this._options);
|
|
353
|
+
this._verticalScrollbar.updateOptions(this._options);
|
|
354
|
+
|
|
355
|
+
if (!this._options.lazyRender) {
|
|
356
|
+
this._render();
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
public setRevealOnScroll(value: boolean) {
|
|
361
|
+
this._revealOnScroll = value;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
public delegateScrollFromMouseWheelEvent(browserEvent: IMouseWheelEvent) {
|
|
365
|
+
this._onMouseWheel(new StandardWheelEvent(browserEvent));
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// -------------------- mouse wheel scrolling --------------------
|
|
369
|
+
|
|
370
|
+
private _setListeningToMouseWheel(shouldListen: boolean): void {
|
|
371
|
+
const isListening = (this._mouseWheelToDispose.length > 0);
|
|
372
|
+
|
|
373
|
+
if (isListening === shouldListen) {
|
|
374
|
+
// No change
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// Stop listening (if necessary)
|
|
379
|
+
this._mouseWheelToDispose = dispose(this._mouseWheelToDispose);
|
|
380
|
+
|
|
381
|
+
// Start listening (if necessary)
|
|
382
|
+
if (shouldListen) {
|
|
383
|
+
const onMouseWheel = (browserEvent: IMouseWheelEvent) => {
|
|
384
|
+
this._onMouseWheel(new StandardWheelEvent(browserEvent));
|
|
385
|
+
};
|
|
386
|
+
|
|
387
|
+
this._mouseWheelToDispose.push(dom.addDisposableListener(this._listenOnDomNode, dom.EventType.MOUSE_WHEEL, onMouseWheel, { passive: false }));
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
private _onMouseWheel(e: StandardWheelEvent): void {
|
|
392
|
+
if (e.browserEvent?.defaultPrevented) {
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const classifier = MouseWheelClassifier.INSTANCE;
|
|
397
|
+
if (SCROLL_WHEEL_SMOOTH_SCROLL_ENABLED) {
|
|
398
|
+
classifier.acceptStandardWheelEvent(e);
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// useful for creating unit tests:
|
|
402
|
+
// console.log(`${Date.now()}, ${e.deltaY}, ${e.deltaX}`);
|
|
403
|
+
|
|
404
|
+
let didScroll = false;
|
|
405
|
+
|
|
406
|
+
if (e.deltaY || e.deltaX) {
|
|
407
|
+
let deltaY = e.deltaY * this._options.mouseWheelScrollSensitivity;
|
|
408
|
+
let deltaX = e.deltaX * this._options.mouseWheelScrollSensitivity;
|
|
409
|
+
|
|
410
|
+
if (this._options.scrollPredominantAxis) {
|
|
411
|
+
if (this._options.scrollYToX && deltaX + deltaY === 0) {
|
|
412
|
+
// when configured to map Y to X and we both see
|
|
413
|
+
// no dominant axis and X and Y are competing with
|
|
414
|
+
// identical values into opposite directions, we
|
|
415
|
+
// ignore the delta as we cannot make a decision then
|
|
416
|
+
deltaX = deltaY = 0;
|
|
417
|
+
} else if (Math.abs(deltaY) >= Math.abs(deltaX)) {
|
|
418
|
+
deltaX = 0;
|
|
419
|
+
} else {
|
|
420
|
+
deltaY = 0;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
if (this._options.flipAxes) {
|
|
425
|
+
[deltaY, deltaX] = [deltaX, deltaY];
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Convert vertical scrolling to horizontal if shift is held, this
|
|
429
|
+
// is handled at a higher level on Mac
|
|
430
|
+
const shiftConvert = !platform.isMacintosh && e.browserEvent && e.browserEvent.shiftKey;
|
|
431
|
+
if ((this._options.scrollYToX || shiftConvert) && !deltaX) {
|
|
432
|
+
deltaX = deltaY;
|
|
433
|
+
deltaY = 0;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (e.browserEvent && e.browserEvent.altKey) {
|
|
437
|
+
// fastScrolling
|
|
438
|
+
deltaX = deltaX * this._options.fastScrollSensitivity;
|
|
439
|
+
deltaY = deltaY * this._options.fastScrollSensitivity;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
const futureScrollPosition = this._scrollable.getFutureScrollPosition();
|
|
443
|
+
|
|
444
|
+
let desiredScrollPosition: INewScrollPosition = {};
|
|
445
|
+
if (deltaY) {
|
|
446
|
+
const deltaScrollTop = SCROLL_WHEEL_SENSITIVITY * deltaY;
|
|
447
|
+
// Here we convert values such as -0.3 to -1 or 0.3 to 1, otherwise low speed scrolling will never scroll
|
|
448
|
+
const desiredScrollTop = futureScrollPosition.scrollTop - (deltaScrollTop < 0 ? Math.floor(deltaScrollTop) : Math.ceil(deltaScrollTop));
|
|
449
|
+
this._verticalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollTop);
|
|
450
|
+
}
|
|
451
|
+
if (deltaX) {
|
|
452
|
+
const deltaScrollLeft = SCROLL_WHEEL_SENSITIVITY * deltaX;
|
|
453
|
+
// Here we convert values such as -0.3 to -1 or 0.3 to 1, otherwise low speed scrolling will never scroll
|
|
454
|
+
const desiredScrollLeft = futureScrollPosition.scrollLeft - (deltaScrollLeft < 0 ? Math.floor(deltaScrollLeft) : Math.ceil(deltaScrollLeft));
|
|
455
|
+
this._horizontalScrollbar.writeScrollPosition(desiredScrollPosition, desiredScrollLeft);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
// Check that we are scrolling towards a location which is valid
|
|
459
|
+
desiredScrollPosition = this._scrollable.validateScrollPosition(desiredScrollPosition);
|
|
460
|
+
|
|
461
|
+
if (futureScrollPosition.scrollLeft !== desiredScrollPosition.scrollLeft || futureScrollPosition.scrollTop !== desiredScrollPosition.scrollTop) {
|
|
462
|
+
|
|
463
|
+
const canPerformSmoothScroll = (
|
|
464
|
+
SCROLL_WHEEL_SMOOTH_SCROLL_ENABLED
|
|
465
|
+
&& this._options.mouseWheelSmoothScroll
|
|
466
|
+
&& classifier.isPhysicalMouseWheel()
|
|
467
|
+
);
|
|
468
|
+
|
|
469
|
+
if (canPerformSmoothScroll) {
|
|
470
|
+
this._scrollable.setScrollPositionSmooth(desiredScrollPosition);
|
|
471
|
+
} else {
|
|
472
|
+
this._scrollable.setScrollPositionNow(desiredScrollPosition);
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
didScroll = true;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
let consumeMouseWheel = didScroll;
|
|
480
|
+
if (!consumeMouseWheel && this._options.alwaysConsumeMouseWheel) {
|
|
481
|
+
consumeMouseWheel = true;
|
|
482
|
+
}
|
|
483
|
+
if (!consumeMouseWheel && this._options.consumeMouseWheelIfScrollbarIsNeeded && (this._verticalScrollbar.isNeeded() || this._horizontalScrollbar.isNeeded())) {
|
|
484
|
+
consumeMouseWheel = true;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
if (consumeMouseWheel) {
|
|
488
|
+
e.preventDefault();
|
|
489
|
+
e.stopPropagation();
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
private _onDidScroll(e: ScrollEvent): void {
|
|
494
|
+
this._shouldRender = this._horizontalScrollbar.onDidScroll(e) || this._shouldRender;
|
|
495
|
+
this._shouldRender = this._verticalScrollbar.onDidScroll(e) || this._shouldRender;
|
|
496
|
+
|
|
497
|
+
if (this._options.useShadows) {
|
|
498
|
+
this._shouldRender = true;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
if (this._revealOnScroll) {
|
|
502
|
+
this._reveal();
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (!this._options.lazyRender) {
|
|
506
|
+
this._render();
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* Render / mutate the DOM now.
|
|
512
|
+
* Should be used together with the ctor option `lazyRender`.
|
|
513
|
+
*/
|
|
514
|
+
public renderNow(): void {
|
|
515
|
+
if (!this._options.lazyRender) {
|
|
516
|
+
throw new Error('Please use `lazyRender` together with `renderNow`!');
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
this._render();
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
private _render(): void {
|
|
523
|
+
if (!this._shouldRender) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
this._shouldRender = false;
|
|
528
|
+
|
|
529
|
+
this._horizontalScrollbar.render();
|
|
530
|
+
this._verticalScrollbar.render();
|
|
531
|
+
|
|
532
|
+
if (this._options.useShadows) {
|
|
533
|
+
const scrollState = this._scrollable.getCurrentScrollPosition();
|
|
534
|
+
const enableTop = scrollState.scrollTop > 0;
|
|
535
|
+
const enableLeft = scrollState.scrollLeft > 0;
|
|
536
|
+
|
|
537
|
+
const leftClassName = (enableLeft ? ' left' : '');
|
|
538
|
+
const topClassName = (enableTop ? ' top' : '');
|
|
539
|
+
const topLeftClassName = (enableLeft || enableTop ? ' top-left-corner' : '');
|
|
540
|
+
this._leftShadowDomNode!.setClassName(`shadow${leftClassName}`);
|
|
541
|
+
this._topShadowDomNode!.setClassName(`shadow${topClassName}`);
|
|
542
|
+
this._topLeftShadowDomNode!.setClassName(`shadow${topLeftClassName}${topClassName}${leftClassName}`);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
// -------------------- fade in / fade out --------------------
|
|
547
|
+
|
|
548
|
+
private _onDragStart(): void {
|
|
549
|
+
this._isDragging = true;
|
|
550
|
+
this._reveal();
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
private _onDragEnd(): void {
|
|
554
|
+
this._isDragging = false;
|
|
555
|
+
this._hide();
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
private _onMouseLeave(e: IMouseEvent): void {
|
|
559
|
+
this._mouseIsOver = false;
|
|
560
|
+
this._hide();
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
private _onMouseOver(e: IMouseEvent): void {
|
|
564
|
+
this._mouseIsOver = true;
|
|
565
|
+
this._reveal();
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
private _reveal(): void {
|
|
569
|
+
this._verticalScrollbar.beginReveal();
|
|
570
|
+
this._horizontalScrollbar.beginReveal();
|
|
571
|
+
this._scheduleHide();
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
private _hide(): void {
|
|
575
|
+
if (!this._mouseIsOver && !this._isDragging) {
|
|
576
|
+
this._verticalScrollbar.beginHide();
|
|
577
|
+
this._horizontalScrollbar.beginHide();
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
private _scheduleHide(): void {
|
|
582
|
+
if (!this._mouseIsOver && !this._isDragging) {
|
|
583
|
+
this._hideTimeout.cancelAndSet(() => this._hide(), HIDE_TIMEOUT);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
export class ScrollableElement extends AbstractScrollableElement {
|
|
589
|
+
|
|
590
|
+
constructor(element: HTMLElement, options: ScrollableElementCreationOptions) {
|
|
591
|
+
options = options || {};
|
|
592
|
+
options.mouseWheelSmoothScroll = false;
|
|
593
|
+
const scrollable = new Scrollable({
|
|
594
|
+
forceIntegerValues: true,
|
|
595
|
+
smoothScrollDuration: 0,
|
|
596
|
+
scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)
|
|
597
|
+
});
|
|
598
|
+
super(element, options, scrollable);
|
|
599
|
+
this._register(scrollable);
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
public setScrollPosition(update: INewScrollPosition): void {
|
|
603
|
+
this._scrollable.setScrollPositionNow(update);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
public getScrollPosition(): IScrollPosition {
|
|
607
|
+
return this._scrollable.getCurrentScrollPosition();
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
export class SmoothScrollableElement extends AbstractScrollableElement {
|
|
612
|
+
|
|
613
|
+
constructor(element: HTMLElement, options: ScrollableElementCreationOptions, scrollable: Scrollable) {
|
|
614
|
+
super(element, options, scrollable);
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
public setScrollPosition(update: INewScrollPosition & { reuseAnimation?: boolean }): void {
|
|
618
|
+
if (update.reuseAnimation) {
|
|
619
|
+
this._scrollable.setScrollPositionSmooth(update, update.reuseAnimation);
|
|
620
|
+
} else {
|
|
621
|
+
this._scrollable.setScrollPositionNow(update);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
public getScrollPosition(): IScrollPosition {
|
|
626
|
+
return this._scrollable.getCurrentScrollPosition();
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export class DomScrollableElement extends AbstractScrollableElement {
|
|
632
|
+
|
|
633
|
+
private _element: HTMLElement;
|
|
634
|
+
|
|
635
|
+
constructor(element: HTMLElement, options: ScrollableElementCreationOptions) {
|
|
636
|
+
options = options || {};
|
|
637
|
+
options.mouseWheelSmoothScroll = false;
|
|
638
|
+
const scrollable = new Scrollable({
|
|
639
|
+
forceIntegerValues: false, // See https://github.com/microsoft/vscode/issues/139877
|
|
640
|
+
smoothScrollDuration: 0,
|
|
641
|
+
scheduleAtNextAnimationFrame: (callback) => dom.scheduleAtNextAnimationFrame(dom.getWindow(element), callback)
|
|
642
|
+
});
|
|
643
|
+
super(element, options, scrollable);
|
|
644
|
+
this._register(scrollable);
|
|
645
|
+
this._element = element;
|
|
646
|
+
this._register(this.onScroll((e) => {
|
|
647
|
+
if (e.scrollTopChanged) {
|
|
648
|
+
this._element.scrollTop = e.scrollTop;
|
|
649
|
+
}
|
|
650
|
+
if (e.scrollLeftChanged) {
|
|
651
|
+
this._element.scrollLeft = e.scrollLeft;
|
|
652
|
+
}
|
|
653
|
+
}));
|
|
654
|
+
this.scanDomNode();
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
public setScrollPosition(update: INewScrollPosition): void {
|
|
658
|
+
this._scrollable.setScrollPositionNow(update);
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
public getScrollPosition(): IScrollPosition {
|
|
662
|
+
return this._scrollable.getCurrentScrollPosition();
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
public scanDomNode(): void {
|
|
666
|
+
// width, scrollLeft, scrollWidth, height, scrollTop, scrollHeight
|
|
667
|
+
this.setScrollDimensions({
|
|
668
|
+
width: this._element.clientWidth,
|
|
669
|
+
scrollWidth: this._element.scrollWidth,
|
|
670
|
+
height: this._element.clientHeight,
|
|
671
|
+
scrollHeight: this._element.scrollHeight
|
|
672
|
+
});
|
|
673
|
+
this.setScrollPosition({
|
|
674
|
+
scrollLeft: this._element.scrollLeft,
|
|
675
|
+
scrollTop: this._element.scrollTop,
|
|
676
|
+
});
|
|
677
|
+
}
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
function resolveOptions(opts: ScrollableElementCreationOptions): ScrollableElementResolvedOptions {
|
|
681
|
+
const result: ScrollableElementResolvedOptions = {
|
|
682
|
+
lazyRender: (typeof opts.lazyRender !== 'undefined' ? opts.lazyRender : false),
|
|
683
|
+
className: (typeof opts.className !== 'undefined' ? opts.className : ''),
|
|
684
|
+
useShadows: (typeof opts.useShadows !== 'undefined' ? opts.useShadows : true),
|
|
685
|
+
handleMouseWheel: (typeof opts.handleMouseWheel !== 'undefined' ? opts.handleMouseWheel : true),
|
|
686
|
+
flipAxes: (typeof opts.flipAxes !== 'undefined' ? opts.flipAxes : false),
|
|
687
|
+
consumeMouseWheelIfScrollbarIsNeeded: (typeof opts.consumeMouseWheelIfScrollbarIsNeeded !== 'undefined' ? opts.consumeMouseWheelIfScrollbarIsNeeded : false),
|
|
688
|
+
alwaysConsumeMouseWheel: (typeof opts.alwaysConsumeMouseWheel !== 'undefined' ? opts.alwaysConsumeMouseWheel : false),
|
|
689
|
+
scrollYToX: (typeof opts.scrollYToX !== 'undefined' ? opts.scrollYToX : false),
|
|
690
|
+
mouseWheelScrollSensitivity: (typeof opts.mouseWheelScrollSensitivity !== 'undefined' ? opts.mouseWheelScrollSensitivity : 1),
|
|
691
|
+
fastScrollSensitivity: (typeof opts.fastScrollSensitivity !== 'undefined' ? opts.fastScrollSensitivity : 5),
|
|
692
|
+
scrollPredominantAxis: (typeof opts.scrollPredominantAxis !== 'undefined' ? opts.scrollPredominantAxis : true),
|
|
693
|
+
mouseWheelSmoothScroll: (typeof opts.mouseWheelSmoothScroll !== 'undefined' ? opts.mouseWheelSmoothScroll : true),
|
|
694
|
+
arrowSize: (typeof opts.arrowSize !== 'undefined' ? opts.arrowSize : 11),
|
|
695
|
+
|
|
696
|
+
listenOnDomNode: (typeof opts.listenOnDomNode !== 'undefined' ? opts.listenOnDomNode : null),
|
|
697
|
+
|
|
698
|
+
horizontal: (typeof opts.horizontal !== 'undefined' ? opts.horizontal : ScrollbarVisibility.Auto),
|
|
699
|
+
horizontalScrollbarSize: (typeof opts.horizontalScrollbarSize !== 'undefined' ? opts.horizontalScrollbarSize : 10),
|
|
700
|
+
horizontalSliderSize: (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : 0),
|
|
701
|
+
horizontalHasArrows: (typeof opts.horizontalHasArrows !== 'undefined' ? opts.horizontalHasArrows : false),
|
|
702
|
+
|
|
703
|
+
vertical: (typeof opts.vertical !== 'undefined' ? opts.vertical : ScrollbarVisibility.Auto),
|
|
704
|
+
verticalScrollbarSize: (typeof opts.verticalScrollbarSize !== 'undefined' ? opts.verticalScrollbarSize : 10),
|
|
705
|
+
verticalHasArrows: (typeof opts.verticalHasArrows !== 'undefined' ? opts.verticalHasArrows : false),
|
|
706
|
+
verticalSliderSize: (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : 0),
|
|
707
|
+
|
|
708
|
+
scrollByPage: (typeof opts.scrollByPage !== 'undefined' ? opts.scrollByPage : false)
|
|
709
|
+
};
|
|
710
|
+
|
|
711
|
+
result.horizontalSliderSize = (typeof opts.horizontalSliderSize !== 'undefined' ? opts.horizontalSliderSize : result.horizontalScrollbarSize);
|
|
712
|
+
result.verticalSliderSize = (typeof opts.verticalSliderSize !== 'undefined' ? opts.verticalSliderSize : result.verticalScrollbarSize);
|
|
713
|
+
|
|
714
|
+
// Defaults are different on Macs
|
|
715
|
+
if (platform.isMacintosh) {
|
|
716
|
+
result.className += ' mac';
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
return result;
|
|
720
|
+
}
|