@xterm/xterm 6.1.0-beta.19 → 6.1.0-beta.191
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 +60 -38
- package/css/xterm.css +29 -22
- package/lib/xterm.js +1 -1
- package/lib/xterm.js.map +1 -1
- package/lib/xterm.mjs +8 -34
- package/lib/xterm.mjs.map +4 -4
- package/package.json +25 -14
- package/src/browser/AccessibilityManager.ts +6 -3
- package/src/browser/Clipboard.ts +6 -3
- package/src/browser/CoreBrowserTerminal.ts +147 -318
- package/src/browser/Dom.ts +178 -0
- package/src/browser/Linkifier.ts +11 -11
- package/src/browser/OscLinkProvider.ts +3 -1
- package/src/browser/RenderDebouncer.ts +2 -2
- package/src/browser/TimeBasedDebouncer.ts +2 -2
- package/src/browser/Types.ts +12 -11
- package/src/browser/Viewport.ts +37 -20
- package/src/browser/decorations/BufferDecorationRenderer.ts +1 -1
- package/src/browser/decorations/OverviewRulerRenderer.ts +15 -16
- package/src/browser/input/CompositionHelper.ts +44 -8
- package/src/browser/public/Terminal.ts +25 -28
- package/src/browser/renderer/dom/DomRenderer.ts +131 -8
- package/src/browser/renderer/dom/DomRendererRowFactory.ts +19 -13
- package/src/browser/renderer/dom/WidthCache.ts +54 -52
- package/src/browser/renderer/shared/Constants.ts +7 -0
- package/src/browser/renderer/shared/TextBlinkStateManager.ts +97 -0
- package/src/browser/renderer/shared/Types.ts +8 -2
- package/src/browser/scrollable/abstractScrollbar.ts +300 -0
- package/src/browser/scrollable/fastDomNode.ts +126 -0
- package/src/browser/scrollable/globalPointerMoveMonitor.ts +90 -0
- package/src/browser/scrollable/horizontalScrollbar.ts +85 -0
- package/src/browser/scrollable/mouseEvent.ts +292 -0
- package/src/browser/scrollable/scrollable.ts +486 -0
- package/src/browser/scrollable/scrollableElement.ts +579 -0
- package/src/browser/scrollable/scrollableElementOptions.ts +161 -0
- package/src/browser/scrollable/scrollbarArrow.ts +110 -0
- package/src/browser/scrollable/scrollbarState.ts +246 -0
- package/src/browser/scrollable/scrollbarVisibilityController.ts +113 -0
- package/src/browser/scrollable/touch.ts +485 -0
- package/src/browser/scrollable/verticalScrollbar.ts +143 -0
- package/src/browser/scrollable/widget.ts +23 -0
- package/src/browser/services/CharSizeService.ts +2 -2
- package/src/browser/services/CoreBrowserService.ts +7 -5
- package/src/browser/services/KeyboardService.ts +67 -0
- package/src/browser/services/LinkProviderService.ts +1 -1
- package/src/browser/services/MouseCoordsService.ts +47 -0
- package/src/browser/services/MouseService.ts +518 -25
- package/src/browser/services/RenderService.ts +22 -15
- package/src/browser/services/SelectionService.ts +16 -8
- package/src/browser/services/Services.ts +40 -17
- package/src/browser/services/ThemeService.ts +2 -2
- package/src/common/Async.ts +105 -0
- package/src/common/CircularList.ts +2 -2
- package/src/common/Color.ts +8 -0
- package/src/common/CoreTerminal.ts +28 -18
- package/src/common/Event.ts +118 -0
- package/src/common/InputHandler.ts +256 -36
- package/src/common/Lifecycle.ts +113 -0
- package/src/common/Platform.ts +13 -3
- package/src/common/SortedList.ts +7 -3
- package/src/common/TaskQueue.ts +9 -3
- package/src/common/Types.ts +35 -15
- package/src/common/Version.ts +9 -0
- package/src/common/buffer/Buffer.ts +20 -14
- package/src/common/buffer/BufferLine.ts +4 -5
- package/src/common/buffer/BufferSet.ts +7 -6
- package/src/common/buffer/CellData.ts +57 -0
- package/src/common/buffer/Marker.ts +2 -2
- package/src/common/buffer/Types.ts +6 -2
- package/src/common/data/EscapeSequences.ts +71 -70
- package/src/common/input/Keyboard.ts +14 -7
- package/src/common/input/KittyKeyboard.ts +496 -0
- package/src/common/input/Win32InputMode.ts +297 -0
- package/src/common/input/WriteBuffer.ts +34 -2
- package/src/common/input/XParseColor.ts +2 -2
- package/src/common/parser/ApcParser.ts +245 -0
- package/src/common/parser/Constants.ts +22 -4
- package/src/common/parser/DcsParser.ts +5 -5
- package/src/common/parser/EscapeSequenceParser.ts +75 -22
- package/src/common/parser/OscParser.ts +5 -5
- package/src/common/parser/Types.ts +34 -1
- package/src/common/public/BufferLineApiView.ts +2 -2
- package/src/common/public/BufferNamespaceApi.ts +2 -2
- package/src/common/public/ParserApi.ts +3 -0
- package/src/common/services/BufferService.ts +8 -5
- package/src/common/services/CharsetService.ts +4 -0
- package/src/common/services/CoreService.ts +18 -4
- package/src/common/services/DecorationService.ts +24 -8
- package/src/common/services/LogService.ts +1 -31
- package/src/common/services/{CoreMouseService.ts → MouseStateService.ts} +21 -132
- package/src/common/services/OptionsService.ts +13 -4
- package/src/common/services/Services.ts +47 -40
- package/src/common/services/UnicodeService.ts +1 -1
- package/typings/xterm.d.ts +319 -35
- package/src/common/TypedArrayUtils.ts +0 -17
- package/src/vs/base/browser/browser.ts +0 -141
- package/src/vs/base/browser/canIUse.ts +0 -49
- package/src/vs/base/browser/dom.ts +0 -2369
- package/src/vs/base/browser/fastDomNode.ts +0 -316
- package/src/vs/base/browser/globalPointerMoveMonitor.ts +0 -112
- package/src/vs/base/browser/iframe.ts +0 -135
- package/src/vs/base/browser/keyboardEvent.ts +0 -213
- package/src/vs/base/browser/mouseEvent.ts +0 -229
- package/src/vs/base/browser/touch.ts +0 -372
- package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +0 -303
- package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +0 -720
- package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +0 -165
- package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +0 -114
- package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +0 -243
- package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +0 -118
- package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +0 -116
- package/src/vs/base/browser/ui/widget.ts +0 -57
- package/src/vs/base/browser/window.ts +0 -14
- package/src/vs/base/common/arrays.ts +0 -887
- package/src/vs/base/common/arraysFind.ts +0 -202
- package/src/vs/base/common/assert.ts +0 -71
- package/src/vs/base/common/async.ts +0 -1992
- package/src/vs/base/common/cancellation.ts +0 -148
- package/src/vs/base/common/charCode.ts +0 -450
- package/src/vs/base/common/collections.ts +0 -140
- package/src/vs/base/common/decorators.ts +0 -130
- package/src/vs/base/common/equals.ts +0 -146
- package/src/vs/base/common/errors.ts +0 -303
- package/src/vs/base/common/event.ts +0 -1778
- package/src/vs/base/common/functional.ts +0 -32
- package/src/vs/base/common/hash.ts +0 -316
- package/src/vs/base/common/iterator.ts +0 -159
- package/src/vs/base/common/keyCodes.ts +0 -526
- package/src/vs/base/common/keybindings.ts +0 -284
- package/src/vs/base/common/lazy.ts +0 -47
- package/src/vs/base/common/lifecycle.ts +0 -801
- package/src/vs/base/common/linkedList.ts +0 -142
- package/src/vs/base/common/map.ts +0 -202
- package/src/vs/base/common/numbers.ts +0 -98
- package/src/vs/base/common/observable.ts +0 -76
- package/src/vs/base/common/observableInternal/api.ts +0 -31
- package/src/vs/base/common/observableInternal/autorun.ts +0 -281
- package/src/vs/base/common/observableInternal/base.ts +0 -489
- package/src/vs/base/common/observableInternal/debugName.ts +0 -145
- package/src/vs/base/common/observableInternal/derived.ts +0 -428
- package/src/vs/base/common/observableInternal/lazyObservableValue.ts +0 -146
- package/src/vs/base/common/observableInternal/logging.ts +0 -328
- package/src/vs/base/common/observableInternal/promise.ts +0 -209
- package/src/vs/base/common/observableInternal/utils.ts +0 -610
- package/src/vs/base/common/platform.ts +0 -281
- package/src/vs/base/common/scrollable.ts +0 -522
- package/src/vs/base/common/sequence.ts +0 -34
- package/src/vs/base/common/stopwatch.ts +0 -43
- package/src/vs/base/common/strings.ts +0 -557
- package/src/vs/base/common/symbols.ts +0 -9
- package/src/vs/base/common/uint.ts +0 -59
- package/src/vs/patches/nls.ts +0 -90
- package/src/vs/typings/base-common.d.ts +0 -20
- package/src/vs/typings/require.d.ts +0 -42
- package/src/vs/typings/vscode-globals-nls.d.ts +0 -36
- package/src/vs/typings/vscode-globals-product.d.ts +0 -33
|
@@ -30,6 +30,12 @@ export class CompositionHelper {
|
|
|
30
30
|
*/
|
|
31
31
|
private _compositionPosition: IPosition;
|
|
32
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Text that existed after the composing range when composition started.
|
|
35
|
+
* This is used to avoid treating existing trailing text as new input.
|
|
36
|
+
*/
|
|
37
|
+
private _compositionSuffix: string;
|
|
38
|
+
|
|
33
39
|
/**
|
|
34
40
|
* Whether a composition is in the process of being sent, setting this to false will cancel any
|
|
35
41
|
* in-progress composition.
|
|
@@ -41,6 +47,11 @@ export class CompositionHelper {
|
|
|
41
47
|
*/
|
|
42
48
|
private _dataAlreadySent: string;
|
|
43
49
|
|
|
50
|
+
/**
|
|
51
|
+
* The pending textarea change timer, if any.
|
|
52
|
+
*/
|
|
53
|
+
private _textareaChangeTimer?: number;
|
|
54
|
+
|
|
44
55
|
constructor(
|
|
45
56
|
private readonly _textarea: HTMLTextAreaElement,
|
|
46
57
|
private readonly _compositionView: HTMLElement,
|
|
@@ -52,6 +63,7 @@ export class CompositionHelper {
|
|
|
52
63
|
this._isComposing = false;
|
|
53
64
|
this._isSendingComposition = false;
|
|
54
65
|
this._compositionPosition = { start: 0, end: 0 };
|
|
66
|
+
this._compositionSuffix = '';
|
|
55
67
|
this._dataAlreadySent = '';
|
|
56
68
|
}
|
|
57
69
|
|
|
@@ -60,7 +72,13 @@ export class CompositionHelper {
|
|
|
60
72
|
*/
|
|
61
73
|
public compositionstart(): void {
|
|
62
74
|
this._isComposing = true;
|
|
63
|
-
|
|
75
|
+
// It's important to use the selection here instead of textarea length to avoid conflicts with
|
|
76
|
+
// screen reader mode
|
|
77
|
+
const start = this._textarea.selectionStart ?? this._textarea.value.length;
|
|
78
|
+
const end = this._textarea.selectionEnd ?? start;
|
|
79
|
+
this._compositionPosition.start = Math.min(start, end);
|
|
80
|
+
this._compositionPosition.end = Math.max(start, end);
|
|
81
|
+
this._compositionSuffix = this._textarea.value.substring(this._compositionPosition.end);
|
|
64
82
|
this._compositionView.textContent = '';
|
|
65
83
|
this._dataAlreadySent = '';
|
|
66
84
|
this._compositionView.classList.add('active');
|
|
@@ -71,10 +89,13 @@ export class CompositionHelper {
|
|
|
71
89
|
* @param ev The event.
|
|
72
90
|
*/
|
|
73
91
|
public compositionupdate(ev: Pick<CompositionEvent, 'data'>): void {
|
|
74
|
-
|
|
92
|
+
// Mark text as LTR, direction=rtl is used in CSS so the end of the text is followed for long
|
|
93
|
+
// compositions
|
|
94
|
+
this._compositionView.textContent = `\u200E${ev.data}\u200E`;
|
|
75
95
|
this.updateCompositionElements();
|
|
76
96
|
setTimeout(() => {
|
|
77
|
-
this.
|
|
97
|
+
const end = this._textarea.selectionEnd ?? this._textarea.value.length;
|
|
98
|
+
this._compositionPosition.end = Math.max( this._compositionPosition.start, end);
|
|
78
99
|
}, 0);
|
|
79
100
|
}
|
|
80
101
|
|
|
@@ -141,6 +162,7 @@ export class CompositionHelper {
|
|
|
141
162
|
start: this._compositionPosition.start,
|
|
142
163
|
end: this._compositionPosition.end
|
|
143
164
|
};
|
|
165
|
+
const currentCompositionSuffix = this._compositionSuffix;
|
|
144
166
|
|
|
145
167
|
// Since composition* events happen before the changes take place in the textarea on most
|
|
146
168
|
// browsers, use a setTimeout with 0ms time to allow the native compositionend event to
|
|
@@ -164,10 +186,14 @@ export class CompositionHelper {
|
|
|
164
186
|
// if a new composition has started.
|
|
165
187
|
input = this._textarea.value.substring(currentCompositionPosition.start, this._compositionPosition.start);
|
|
166
188
|
} else {
|
|
167
|
-
//
|
|
168
|
-
//
|
|
169
|
-
//
|
|
170
|
-
|
|
189
|
+
// Keep support for non-composition characters typed immediately after composition end
|
|
190
|
+
// while avoiding re-sending the trailing text that was already present
|
|
191
|
+
// before composition started.
|
|
192
|
+
const value = this._textarea.value;
|
|
193
|
+
const valueEnd = currentCompositionSuffix.length > 0 && value.endsWith(currentCompositionSuffix)
|
|
194
|
+
? value.length - currentCompositionSuffix.length
|
|
195
|
+
: value.length;
|
|
196
|
+
input = value.substring(currentCompositionPosition.start, Math.max(currentCompositionPosition.start, valueEnd));
|
|
171
197
|
}
|
|
172
198
|
if (input.length > 0) {
|
|
173
199
|
this._coreService.triggerDataEvent(input, true);
|
|
@@ -184,8 +210,12 @@ export class CompositionHelper {
|
|
|
184
210
|
* IME is active.
|
|
185
211
|
*/
|
|
186
212
|
private _handleAnyTextareaChanges(): void {
|
|
213
|
+
if (this._textareaChangeTimer) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
187
216
|
const oldValue = this._textarea.value;
|
|
188
|
-
setTimeout(() => {
|
|
217
|
+
this._textareaChangeTimer = window.setTimeout(() => {
|
|
218
|
+
this._textareaChangeTimer = undefined;
|
|
189
219
|
// Ignore if a composition has started since the timeout
|
|
190
220
|
if (!this._isComposing) {
|
|
191
221
|
const newValue = this._textarea.value;
|
|
@@ -230,6 +260,12 @@ export class CompositionHelper {
|
|
|
230
260
|
this._compositionView.style.lineHeight = cellHeight + 'px';
|
|
231
261
|
this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;
|
|
232
262
|
this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';
|
|
263
|
+
// Limit the composition view width to the space between the cursor and
|
|
264
|
+
// the terminal's right edge, preventing it from overflowing the terminal.
|
|
265
|
+
const maxWidth = this._bufferService.cols * this._renderService.dimensions.css.cell.width - cursorLeft;
|
|
266
|
+
this._compositionView.style.maxWidth = maxWidth + 'px';
|
|
267
|
+
this._compositionView.style.overflow = 'hidden';
|
|
268
|
+
this._compositionView.style.direction = 'rtl';
|
|
233
269
|
// Sync the textarea to the exact position of the composition view so the IME knows where the
|
|
234
270
|
// text is.
|
|
235
271
|
const compositionViewBounds = this._compositionView.getBoundingClientRect();
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
import * as Strings from 'browser/LocalizableStrings';
|
|
7
7
|
import { CoreBrowserTerminal as TerminalCore } from 'browser/CoreBrowserTerminal';
|
|
8
8
|
import { IBufferRange, ITerminal } from 'browser/Types';
|
|
9
|
-
import { Disposable } from '
|
|
9
|
+
import { Disposable } from 'common/Lifecycle';
|
|
10
10
|
import { ITerminalOptions } from 'common/Types';
|
|
11
11
|
import { AddonManager } from 'common/public/AddonManager';
|
|
12
12
|
import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi';
|
|
13
13
|
import { ParserApi } from 'common/public/ParserApi';
|
|
14
14
|
import { UnicodeApi } from 'common/public/UnicodeApi';
|
|
15
|
-
import { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';
|
|
16
|
-
import type {
|
|
15
|
+
import { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, IRenderDimensions, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';
|
|
16
|
+
import type { IEvent } from 'common/Event';
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* The set of options that only have an effect when set in the Terminal constructor.
|
|
@@ -68,25 +68,24 @@ export class Terminal extends Disposable implements ITerminalApi {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
public get onBell():
|
|
72
|
-
public get onBinary():
|
|
73
|
-
public get onCursorMove():
|
|
74
|
-
public get onData():
|
|
75
|
-
public get onKey():
|
|
76
|
-
public get onLineFeed():
|
|
77
|
-
public get onRender():
|
|
78
|
-
public get onResize():
|
|
79
|
-
public get onScroll():
|
|
80
|
-
public get onSelectionChange():
|
|
81
|
-
public get onTitleChange():
|
|
82
|
-
public get onWriteParsed():
|
|
71
|
+
public get onBell(): IEvent<void> { return this._core.onBell; }
|
|
72
|
+
public get onBinary(): IEvent<string> { return this._core.onBinary; }
|
|
73
|
+
public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
|
|
74
|
+
public get onData(): IEvent<string> { return this._core.onData; }
|
|
75
|
+
public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }
|
|
76
|
+
public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
|
|
77
|
+
public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }
|
|
78
|
+
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }
|
|
79
|
+
public get onScroll(): IEvent<number> { return this._core.onScroll; }
|
|
80
|
+
public get onSelectionChange(): IEvent<void> { return this._core.onSelectionChange; }
|
|
81
|
+
public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
|
|
82
|
+
public get onWriteParsed(): IEvent<void> { return this._core.onWriteParsed; }
|
|
83
|
+
public get onDimensionsChange(): IEvent<IRenderDimensions> { return this._core.onDimensionsChange; }
|
|
83
84
|
|
|
84
85
|
public get element(): HTMLElement | undefined { return this._core.element; }
|
|
86
|
+
public get screenElement(): HTMLElement | undefined { return this._core.screenElement; }
|
|
85
87
|
public get parser(): IParser {
|
|
86
|
-
|
|
87
|
-
this._parser = new ParserApi(this._core);
|
|
88
|
-
}
|
|
89
|
-
return this._parser;
|
|
88
|
+
return this._parser ??= new ParserApi(this._core);
|
|
90
89
|
}
|
|
91
90
|
public get unicode(): IUnicodeHandling {
|
|
92
91
|
this._checkProposedApi();
|
|
@@ -96,19 +95,15 @@ export class Terminal extends Disposable implements ITerminalApi {
|
|
|
96
95
|
public get rows(): number { return this._core.rows; }
|
|
97
96
|
public get cols(): number { return this._core.cols; }
|
|
98
97
|
public get buffer(): IBufferNamespaceApi {
|
|
99
|
-
|
|
100
|
-
this._buffer = this._register(new BufferNamespaceApi(this._core));
|
|
101
|
-
}
|
|
102
|
-
return this._buffer;
|
|
98
|
+
return this._buffer ??= this._register(new BufferNamespaceApi(this._core));
|
|
103
99
|
}
|
|
104
100
|
public get markers(): ReadonlyArray<IMarker> {
|
|
105
|
-
this._checkProposedApi();
|
|
106
101
|
return this._core.markers;
|
|
107
102
|
}
|
|
108
103
|
public get modes(): IModes {
|
|
109
104
|
const m = this._core.coreService.decPrivateModes;
|
|
110
105
|
let mouseTrackingMode: 'none' | 'x10' | 'vt200' | 'drag' | 'any' = 'none';
|
|
111
|
-
switch (this._core.
|
|
106
|
+
switch (this._core.mouseStateService.activeProtocol) {
|
|
112
107
|
case 'X10': mouseTrackingMode = 'x10'; break;
|
|
113
108
|
case 'VT200': mouseTrackingMode = 'vt200'; break;
|
|
114
109
|
case 'DRAG': mouseTrackingMode = 'drag'; break;
|
|
@@ -123,10 +118,15 @@ export class Terminal extends Disposable implements ITerminalApi {
|
|
|
123
118
|
originMode: m.origin,
|
|
124
119
|
reverseWraparoundMode: m.reverseWraparound,
|
|
125
120
|
sendFocusMode: m.sendFocus,
|
|
121
|
+
showCursor: !this._core.coreService.isCursorHidden,
|
|
126
122
|
synchronizedOutputMode: m.synchronizedOutput,
|
|
123
|
+
win32InputMode: m.win32InputMode,
|
|
127
124
|
wraparoundMode: m.wraparound
|
|
128
125
|
};
|
|
129
126
|
}
|
|
127
|
+
public get dimensions(): IRenderDimensions | undefined {
|
|
128
|
+
return this._core.dimensions;
|
|
129
|
+
}
|
|
130
130
|
public get options(): Required<ITerminalOptions> {
|
|
131
131
|
return this._publicOptions;
|
|
132
132
|
}
|
|
@@ -161,11 +161,9 @@ export class Terminal extends Disposable implements ITerminalApi {
|
|
|
161
161
|
return this._core.registerLinkProvider(linkProvider);
|
|
162
162
|
}
|
|
163
163
|
public registerCharacterJoiner(handler: (text: string) => [number, number][]): number {
|
|
164
|
-
this._checkProposedApi();
|
|
165
164
|
return this._core.registerCharacterJoiner(handler);
|
|
166
165
|
}
|
|
167
166
|
public deregisterCharacterJoiner(joinerId: number): void {
|
|
168
|
-
this._checkProposedApi();
|
|
169
167
|
this._core.deregisterCharacterJoiner(joinerId);
|
|
170
168
|
}
|
|
171
169
|
public registerMarker(cursorYOffset: number = 0): IMarker {
|
|
@@ -173,7 +171,6 @@ export class Terminal extends Disposable implements ITerminalApi {
|
|
|
173
171
|
return this._core.registerMarker(cursorYOffset);
|
|
174
172
|
}
|
|
175
173
|
public registerDecoration(decorationOptions: IDecorationOptions): IDecoration | undefined {
|
|
176
|
-
this._checkProposedApi();
|
|
177
174
|
this._verifyPositiveIntegers(decorationOptions.x ?? 0, decorationOptions.width ?? 0, decorationOptions.height ?? 0);
|
|
178
175
|
return this._core.registerDecoration(decorationOptions);
|
|
179
176
|
}
|
|
@@ -5,16 +5,18 @@
|
|
|
5
5
|
|
|
6
6
|
import { DomRendererRowFactory, RowCss } from 'browser/renderer/dom/DomRendererRowFactory';
|
|
7
7
|
import { WidthCache } from 'browser/renderer/dom/WidthCache';
|
|
8
|
-
import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
|
|
8
|
+
import { INVERTED_DEFAULT_COLOR, RendererConstants } from 'browser/renderer/shared/Constants';
|
|
9
9
|
import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
|
|
10
10
|
import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel';
|
|
11
|
+
import { TextBlinkStateManager } from 'browser/renderer/shared/TextBlinkStateManager';
|
|
11
12
|
import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from 'browser/renderer/shared/Types';
|
|
12
13
|
import { ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
|
|
13
14
|
import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from 'browser/Types';
|
|
14
15
|
import { color } from 'common/Color';
|
|
15
|
-
import { Disposable, toDisposable } from '
|
|
16
|
+
import { Disposable, toDisposable } from 'common/Lifecycle';
|
|
16
17
|
import { IBufferService, ICoreService, IInstantiationService, IOptionsService } from 'common/services/Services';
|
|
17
|
-
import { Emitter } from '
|
|
18
|
+
import { Emitter } from 'common/Event';
|
|
19
|
+
import { addDisposableListener } from 'browser/Dom';
|
|
18
20
|
|
|
19
21
|
|
|
20
22
|
const TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-';
|
|
@@ -23,6 +25,7 @@ const FG_CLASS_PREFIX = 'xterm-fg-';
|
|
|
23
25
|
const BG_CLASS_PREFIX = 'xterm-bg-';
|
|
24
26
|
const FOCUS_CLASS = 'xterm-focus';
|
|
25
27
|
const SELECTION_CLASS = 'xterm-selection';
|
|
28
|
+
const CURSOR_BLINK_IDLE_CLASS = 'xterm-cursor-blink-idle';
|
|
26
29
|
|
|
27
30
|
let nextTerminalId = 1;
|
|
28
31
|
|
|
@@ -42,10 +45,15 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
42
45
|
private _selectionContainer: HTMLElement;
|
|
43
46
|
private _widthCache: WidthCache;
|
|
44
47
|
private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();
|
|
48
|
+
private _cursorBlinkStateManager: CursorBlinkStateManager;
|
|
49
|
+
private _textBlinkStateManager: TextBlinkStateManager;
|
|
50
|
+
private _rowHasBlinkingCells: boolean[] = [];
|
|
51
|
+
private _rowHasBlinkingCellsCount: number = 0;
|
|
45
52
|
|
|
46
53
|
public dimensions: IRenderDimensions;
|
|
47
54
|
|
|
48
|
-
|
|
55
|
+
private readonly _onRequestRedraw = this._register(new Emitter<IRequestRedrawEvent>());
|
|
56
|
+
public readonly onRequestRedraw = this._onRequestRedraw.event;
|
|
49
57
|
|
|
50
58
|
constructor(
|
|
51
59
|
private readonly _terminal: ITerminal,
|
|
@@ -89,6 +97,15 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
89
97
|
this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));
|
|
90
98
|
this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));
|
|
91
99
|
|
|
100
|
+
this._cursorBlinkStateManager = new CursorBlinkStateManager(this._rowContainer, this._coreBrowserService);
|
|
101
|
+
this._register(addDisposableListener(this._document, 'mousedown', () => this._cursorBlinkStateManager.restartBlinkAnimation()));
|
|
102
|
+
this._register(toDisposable(() => this._cursorBlinkStateManager.dispose()));
|
|
103
|
+
this._textBlinkStateManager = this._register(new TextBlinkStateManager(
|
|
104
|
+
() => this._onRequestRedraw.fire({ start: 0, end: this._bufferService.rows - 1 }),
|
|
105
|
+
this._coreBrowserService,
|
|
106
|
+
this._optionsService
|
|
107
|
+
));
|
|
108
|
+
|
|
92
109
|
this._register(toDisposable(() => {
|
|
93
110
|
this._element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass);
|
|
94
111
|
|
|
@@ -101,7 +118,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
101
118
|
this._dimensionsStyleElement.remove();
|
|
102
119
|
}));
|
|
103
120
|
|
|
104
|
-
this._widthCache = new WidthCache(
|
|
121
|
+
this._widthCache = new WidthCache();
|
|
105
122
|
this._widthCache.setFont(
|
|
106
123
|
this._optionsService.rawOptions.fontFamily,
|
|
107
124
|
this._optionsService.rawOptions.fontSize,
|
|
@@ -167,6 +184,9 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
167
184
|
// refresh() being called during the mousedown handler to start a selection.
|
|
168
185
|
` pointer-events: none;` +
|
|
169
186
|
` color: ${colors.foreground.css};` +
|
|
187
|
+
`}`;
|
|
188
|
+
styles +=
|
|
189
|
+
`${this._terminalSelector} .${ROW_CONTAINER_CLASS}, ${this._terminalSelector} .${ROW_CONTAINER_CLASS} span {` +
|
|
170
190
|
` font-family: ${this._optionsService.rawOptions.fontFamily};` +
|
|
171
191
|
` font-size: ${this._optionsService.rawOptions.fontSize}px;` +
|
|
172
192
|
` font-kerning: none;` +
|
|
@@ -186,6 +206,9 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
186
206
|
`}` +
|
|
187
207
|
`${this._terminalSelector} span.${RowCss.ITALIC_CLASS} {` +
|
|
188
208
|
` font-style: italic;` +
|
|
209
|
+
`}` +
|
|
210
|
+
`${this._terminalSelector} span.${RowCss.BLINK_HIDDEN_CLASS} {` +
|
|
211
|
+
` visibility: hidden;` +
|
|
189
212
|
`}`;
|
|
190
213
|
// Blink animation
|
|
191
214
|
const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;
|
|
@@ -225,6 +248,10 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
225
248
|
`${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
|
|
226
249
|
` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +
|
|
227
250
|
`}` +
|
|
251
|
+
// Disable cursor blinking when idle
|
|
252
|
+
`${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${CURSOR_BLINK_IDLE_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS} {` +
|
|
253
|
+
` animation: none !important;` +
|
|
254
|
+
`}` +
|
|
228
255
|
// !important helps fix an issue where the cursor will not render on top of the selection,
|
|
229
256
|
// however it's very hard to fix this issue and retain the blink animation without the use of
|
|
230
257
|
// !important. So this edge case fails when cursor blink is on.
|
|
@@ -307,10 +334,14 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
307
334
|
const row = this._document.createElement('div');
|
|
308
335
|
this._rowContainer.appendChild(row);
|
|
309
336
|
this._rowElements.push(row);
|
|
337
|
+
this._rowHasBlinkingCells.push(false);
|
|
310
338
|
}
|
|
311
339
|
// Remove excess elements
|
|
312
340
|
while (this._rowElements.length > rows) {
|
|
313
341
|
this._rowContainer.removeChild(this._rowElements.pop()!);
|
|
342
|
+
if (this._rowHasBlinkingCells.pop()) {
|
|
343
|
+
this._rowHasBlinkingCellsCount--;
|
|
344
|
+
}
|
|
314
345
|
}
|
|
315
346
|
}
|
|
316
347
|
|
|
@@ -328,14 +359,20 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
328
359
|
|
|
329
360
|
public handleBlur(): void {
|
|
330
361
|
this._rowContainer.classList.remove(FOCUS_CLASS);
|
|
362
|
+
this._cursorBlinkStateManager.pause();
|
|
331
363
|
this.renderRows(0, this._bufferService.rows - 1);
|
|
332
364
|
}
|
|
333
365
|
|
|
334
366
|
public handleFocus(): void {
|
|
335
367
|
this._rowContainer.classList.add(FOCUS_CLASS);
|
|
368
|
+
this._cursorBlinkStateManager.resume();
|
|
336
369
|
this.renderRows(this._bufferService.buffer.y, this._bufferService.buffer.y);
|
|
337
370
|
}
|
|
338
371
|
|
|
372
|
+
public handleViewportVisibilityChange(isVisible: boolean): void {
|
|
373
|
+
this._textBlinkStateManager.setViewportVisible(isVisible);
|
|
374
|
+
}
|
|
375
|
+
|
|
339
376
|
public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {
|
|
340
377
|
// Remove all selections
|
|
341
378
|
this._selectionContainer.replaceChildren();
|
|
@@ -406,7 +443,8 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
406
443
|
}
|
|
407
444
|
|
|
408
445
|
public handleCursorMove(): void {
|
|
409
|
-
//
|
|
446
|
+
// Reset idle timer on cursor movement (which happens on input)
|
|
447
|
+
this._cursorBlinkStateManager.restartBlinkAnimation();
|
|
410
448
|
}
|
|
411
449
|
|
|
412
450
|
private _handleOptionsChanged(): void {
|
|
@@ -436,6 +474,11 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
436
474
|
*/
|
|
437
475
|
e.replaceChildren();
|
|
438
476
|
}
|
|
477
|
+
if (this._rowHasBlinkingCellsCount > 0) {
|
|
478
|
+
this._rowHasBlinkingCells.fill(false);
|
|
479
|
+
this._rowHasBlinkingCellsCount = 0;
|
|
480
|
+
this._textBlinkStateManager.setNeedsBlinkInViewport(false);
|
|
481
|
+
}
|
|
439
482
|
}
|
|
440
483
|
|
|
441
484
|
public renderRows(start: number, end: number): void {
|
|
@@ -445,6 +488,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
445
488
|
const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;
|
|
446
489
|
const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;
|
|
447
490
|
const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;
|
|
491
|
+
const rowInfo = { hasBlinkingCells: false };
|
|
448
492
|
|
|
449
493
|
for (let y = start; y <= end; y++) {
|
|
450
494
|
const row = y + buffer.ydisp;
|
|
@@ -462,13 +506,17 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
462
506
|
cursorInactiveStyle,
|
|
463
507
|
cursorX,
|
|
464
508
|
cursorBlink,
|
|
509
|
+
this._textBlinkStateManager.isBlinkOn,
|
|
465
510
|
this.dimensions.css.cell.width,
|
|
466
511
|
this._widthCache,
|
|
467
512
|
-1,
|
|
468
|
-
-1
|
|
513
|
+
-1,
|
|
514
|
+
rowInfo
|
|
469
515
|
)
|
|
470
516
|
);
|
|
517
|
+
this._setRowBlinkState(y, rowInfo.hasBlinkingCells);
|
|
471
518
|
}
|
|
519
|
+
this._updateTextBlinkState();
|
|
472
520
|
}
|
|
473
521
|
|
|
474
522
|
private get _terminalSelector(): string {
|
|
@@ -513,6 +561,7 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
513
561
|
const cursorBlink = this._optionsService.rawOptions.cursorBlink;
|
|
514
562
|
const cursorStyle = this._optionsService.rawOptions.cursorStyle;
|
|
515
563
|
const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;
|
|
564
|
+
const rowInfo = { hasBlinkingCells: false };
|
|
516
565
|
|
|
517
566
|
// refresh rows within link range
|
|
518
567
|
for (let i = y; i <= y2; ++i) {
|
|
@@ -531,12 +580,86 @@ export class DomRenderer extends Disposable implements IRenderer {
|
|
|
531
580
|
cursorInactiveStyle,
|
|
532
581
|
cursorX,
|
|
533
582
|
cursorBlink,
|
|
583
|
+
this._textBlinkStateManager.isBlinkOn,
|
|
534
584
|
this.dimensions.css.cell.width,
|
|
535
585
|
this._widthCache,
|
|
536
586
|
enabled ? (i === y ? x : 0) : -1,
|
|
537
|
-
enabled ? ((i === y2 ? x2 : cols) - 1) : -1
|
|
587
|
+
enabled ? ((i === y2 ? x2 : cols) - 1) : -1,
|
|
588
|
+
rowInfo
|
|
538
589
|
)
|
|
539
590
|
);
|
|
591
|
+
this._setRowBlinkState(i, rowInfo.hasBlinkingCells);
|
|
540
592
|
}
|
|
593
|
+
this._updateTextBlinkState();
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
private _setRowBlinkState(row: number, hasBlinkingCells: boolean): void {
|
|
597
|
+
const previous = this._rowHasBlinkingCells[row];
|
|
598
|
+
if (previous === hasBlinkingCells) {
|
|
599
|
+
return;
|
|
600
|
+
}
|
|
601
|
+
this._rowHasBlinkingCells[row] = hasBlinkingCells;
|
|
602
|
+
this._rowHasBlinkingCellsCount += hasBlinkingCells ? 1 : -1;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
private _updateTextBlinkState(): void {
|
|
606
|
+
this._textBlinkStateManager.setNeedsBlinkInViewport(this._rowHasBlinkingCellsCount > 0);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
class CursorBlinkStateManager {
|
|
611
|
+
private _idleTimeout: number | undefined;
|
|
612
|
+
private _isIdlePaused: boolean = false;
|
|
613
|
+
|
|
614
|
+
constructor(
|
|
615
|
+
private readonly _rowContainer: HTMLElement,
|
|
616
|
+
private readonly _coreBrowserService: ICoreBrowserService
|
|
617
|
+
) {
|
|
618
|
+
if (this._coreBrowserService.isFocused) {
|
|
619
|
+
this._resetIdleTimer();
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
public dispose(): void {
|
|
624
|
+
this._clearIdleTimer();
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
public restartBlinkAnimation(): void {
|
|
628
|
+
if (this._isIdlePaused) {
|
|
629
|
+
this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS);
|
|
630
|
+
}
|
|
631
|
+
this._resetIdleTimer();
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
public pause(): void {
|
|
635
|
+
this._isIdlePaused = false;
|
|
636
|
+
this._clearIdleTimer();
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
public resume(): void {
|
|
640
|
+
this._isIdlePaused = false;
|
|
641
|
+
this._rowContainer.classList.remove(CURSOR_BLINK_IDLE_CLASS);
|
|
642
|
+
this._resetIdleTimer();
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
private _resetIdleTimer(): void {
|
|
646
|
+
this._isIdlePaused = false;
|
|
647
|
+
this._clearIdleTimer();
|
|
648
|
+
this._idleTimeout = this._coreBrowserService.window.setTimeout(() => {
|
|
649
|
+
this._stopBlinkingDueToIdle();
|
|
650
|
+
}, RendererConstants.CURSOR_BLINK_IDLE_TIMEOUT);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
private _clearIdleTimer(): void {
|
|
654
|
+
if (this._idleTimeout) {
|
|
655
|
+
this._coreBrowserService.window.clearTimeout(this._idleTimeout);
|
|
656
|
+
this._idleTimeout = undefined;
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
private _stopBlinkingDueToIdle(): void {
|
|
661
|
+
this._rowContainer.classList.add(CURSOR_BLINK_IDLE_CLASS);
|
|
662
|
+
this._isIdlePaused = true;
|
|
663
|
+
this._idleTimeout = undefined;
|
|
541
664
|
}
|
|
542
665
|
}
|
|
@@ -24,6 +24,7 @@ export const enum RowCss {
|
|
|
24
24
|
UNDERLINE_CLASS = 'xterm-underline',
|
|
25
25
|
OVERLINE_CLASS = 'xterm-overline',
|
|
26
26
|
STRIKETHROUGH_CLASS = 'xterm-strikethrough',
|
|
27
|
+
BLINK_HIDDEN_CLASS = 'xterm-blink-hidden',
|
|
27
28
|
CURSOR_CLASS = 'xterm-cursor',
|
|
28
29
|
CURSOR_BLINK_CLASS = 'xterm-cursor-blink',
|
|
29
30
|
CURSOR_STYLE_BLOCK_CLASS = 'xterm-cursor-block',
|
|
@@ -66,13 +67,18 @@ export class DomRendererRowFactory {
|
|
|
66
67
|
cursorInactiveStyle: string | undefined,
|
|
67
68
|
cursorX: number,
|
|
68
69
|
cursorBlink: boolean,
|
|
70
|
+
blinkOn: boolean,
|
|
69
71
|
cellWidth: number,
|
|
70
72
|
widthCache: WidthCache,
|
|
71
73
|
linkStart: number,
|
|
72
|
-
linkEnd: number
|
|
74
|
+
linkEnd: number,
|
|
75
|
+
rowInfo?: { hasBlinkingCells: boolean }
|
|
73
76
|
): HTMLSpanElement[] {
|
|
74
77
|
|
|
75
78
|
const elements: HTMLSpanElement[] = [];
|
|
79
|
+
if (rowInfo) {
|
|
80
|
+
rowInfo.hasBlinkingCells = false;
|
|
81
|
+
}
|
|
76
82
|
const joinedRanges = this._characterJoinerService.getJoinedCharacters(row);
|
|
77
83
|
const colors = this._themeService.colors;
|
|
78
84
|
|
|
@@ -118,7 +124,7 @@ export class DomRendererRowFactory {
|
|
|
118
124
|
// Process any joined character ranges as needed. Because of how the
|
|
119
125
|
// ranges are produced, we know that they are valid for the characters
|
|
120
126
|
// and attributes of our input.
|
|
121
|
-
let cell = this._workCell;
|
|
127
|
+
let cell: ICellData = this._workCell;
|
|
122
128
|
if (joinedRanges.length > 0 && x === joinedRanges[0][0] && isValidJoinRange) {
|
|
123
129
|
const range = joinedRanges.shift()!;
|
|
124
130
|
// If the ligature's selection state is not consistent, don't join it. This helps the
|
|
@@ -153,6 +159,13 @@ export class DomRendererRowFactory {
|
|
|
153
159
|
const isInSelection = this._isCellInSelection(x, row);
|
|
154
160
|
const isCursorCell = isCursorRow && x === cursorX;
|
|
155
161
|
const isLinkHover = hasHover && x >= linkStart && x <= linkEnd;
|
|
162
|
+
if (rowInfo && cell.isBlink()) {
|
|
163
|
+
rowInfo.hasBlinkingCells = true;
|
|
164
|
+
}
|
|
165
|
+
const isBlinkHidden = !blinkOn && cell.isBlink();
|
|
166
|
+
if (isBlinkHidden) {
|
|
167
|
+
classes.push(RowCss.BLINK_HIDDEN_CLASS);
|
|
168
|
+
}
|
|
156
169
|
|
|
157
170
|
let isDecorated = false;
|
|
158
171
|
this._decorationService.forEachDecorationAtCell(x, row, undefined, d => {
|
|
@@ -397,7 +410,7 @@ export class DomRendererRowFactory {
|
|
|
397
410
|
break;
|
|
398
411
|
case Attributes.CM_RGB:
|
|
399
412
|
resolvedBg = channels.toColor(bg >> 16, bg >> 8 & 0xFF, bg & 0xFF);
|
|
400
|
-
this._addStyle(charElement, `background-color:#${
|
|
413
|
+
this._addStyle(charElement, `background-color:#${(bg >>> 0).toString(16).padStart(6, '0')}`);
|
|
401
414
|
break;
|
|
402
415
|
case Attributes.CM_DEFAULT:
|
|
403
416
|
default:
|
|
@@ -434,7 +447,7 @@ export class DomRendererRowFactory {
|
|
|
434
447
|
(fg ) & 0xFF
|
|
435
448
|
);
|
|
436
449
|
if (!this._applyMinimumContrast(charElement, resolvedBg, color, cell, bgOverride, fgOverride)) {
|
|
437
|
-
this._addStyle(charElement, `color:#${
|
|
450
|
+
this._addStyle(charElement, `color:#${fg.toString(16).padStart(6, '0')}`);
|
|
438
451
|
}
|
|
439
452
|
break;
|
|
440
453
|
case Attributes.CM_DEFAULT:
|
|
@@ -494,8 +507,8 @@ export class DomRendererRowFactory {
|
|
|
494
507
|
// Dim cells only require half the contrast, otherwise they wouldn't be distinguishable from
|
|
495
508
|
// non-dim cells
|
|
496
509
|
const ratio = this._optionsService.rawOptions.minimumContrastRatio / (cell.isDim() ? 2 : 1);
|
|
497
|
-
adjustedColor = color.ensureContrastRatio(bgOverride
|
|
498
|
-
cache.setColor((bgOverride
|
|
510
|
+
adjustedColor = color.ensureContrastRatio(bgOverride ?? bg, fgOverride ?? fg, ratio);
|
|
511
|
+
cache.setColor((bgOverride ?? bg).rgba, (fgOverride ?? fg).rgba, adjustedColor ?? null);
|
|
499
512
|
}
|
|
500
513
|
|
|
501
514
|
if (adjustedColor) {
|
|
@@ -537,10 +550,3 @@ export class DomRendererRowFactory {
|
|
|
537
550
|
(start[1] < end[1] && y === start[1] && x >= start[0]);
|
|
538
551
|
}
|
|
539
552
|
}
|
|
540
|
-
|
|
541
|
-
function padStart(text: string, padChar: string, length: number): string {
|
|
542
|
-
while (text.length < length) {
|
|
543
|
-
text = padChar + text;
|
|
544
|
-
}
|
|
545
|
-
return text;
|
|
546
|
-
}
|