groove-dev 0.16.0 → 0.16.2
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/node_modules/@groove-dev/daemon/src/api.js +122 -1
- package/node_modules/@groove-dev/daemon/src/index.js +25 -7
- package/node_modules/@groove-dev/daemon/src/mimetypes.js +43 -0
- package/node_modules/@groove-dev/daemon/src/terminal-pty.js +129 -0
- package/node_modules/@groove-dev/gui/dist/assets/{index-Gfb8Zxy9.css → index-BhjOFLBc.css} +32 -1
- package/node_modules/@groove-dev/gui/dist/assets/index-DeXW9EFU.js +153 -0
- package/node_modules/@groove-dev/gui/dist/index.html +2 -2
- package/node_modules/@groove-dev/gui/package.json +3 -0
- package/node_modules/@groove-dev/gui/src/components/EditorTabs.jsx +1 -1
- package/node_modules/@groove-dev/gui/src/components/FileTree.jsx +308 -23
- package/node_modules/@groove-dev/gui/src/components/MediaViewer.jsx +104 -0
- package/node_modules/@groove-dev/gui/src/components/Terminal.jsx +154 -0
- package/node_modules/@groove-dev/gui/src/stores/groove.js +131 -2
- package/node_modules/@groove-dev/gui/src/views/FileEditor.jsx +104 -36
- package/node_modules/@xterm/addon-fit/LICENSE +19 -0
- package/node_modules/@xterm/addon-fit/README.md +24 -0
- package/node_modules/@xterm/addon-fit/lib/addon-fit.js +2 -0
- package/node_modules/@xterm/addon-fit/lib/addon-fit.js.map +1 -0
- package/node_modules/@xterm/addon-fit/lib/addon-fit.mjs +18 -0
- package/node_modules/@xterm/addon-fit/lib/addon-fit.mjs.map +7 -0
- package/node_modules/@xterm/addon-fit/package.json +26 -0
- package/node_modules/@xterm/addon-fit/src/FitAddon.ts +92 -0
- package/node_modules/@xterm/addon-fit/typings/addon-fit.d.ts +55 -0
- package/node_modules/@xterm/addon-web-links/LICENSE +19 -0
- package/node_modules/@xterm/addon-web-links/README.md +21 -0
- package/node_modules/@xterm/addon-web-links/lib/addon-web-links.js +2 -0
- package/node_modules/@xterm/addon-web-links/lib/addon-web-links.js.map +1 -0
- package/node_modules/@xterm/addon-web-links/lib/addon-web-links.mjs +18 -0
- package/node_modules/@xterm/addon-web-links/lib/addon-web-links.mjs.map +7 -0
- package/node_modules/@xterm/addon-web-links/package.json +26 -0
- package/node_modules/@xterm/addon-web-links/src/WebLinkProvider.ts +199 -0
- package/node_modules/@xterm/addon-web-links/src/WebLinksAddon.ts +58 -0
- package/node_modules/@xterm/addon-web-links/typings/addon-web-links.d.ts +57 -0
- package/node_modules/@xterm/xterm/LICENSE +21 -0
- package/node_modules/@xterm/xterm/README.md +243 -0
- package/node_modules/@xterm/xterm/css/xterm.css +285 -0
- package/node_modules/@xterm/xterm/lib/xterm.js +2 -0
- package/node_modules/@xterm/xterm/lib/xterm.js.map +1 -0
- package/node_modules/@xterm/xterm/lib/xterm.mjs +53 -0
- package/node_modules/@xterm/xterm/lib/xterm.mjs.map +7 -0
- package/node_modules/@xterm/xterm/package.json +111 -0
- package/node_modules/@xterm/xterm/src/browser/AccessibilityManager.ts +435 -0
- package/node_modules/@xterm/xterm/src/browser/Clipboard.ts +93 -0
- package/node_modules/@xterm/xterm/src/browser/ColorContrastCache.ts +34 -0
- package/node_modules/@xterm/xterm/src/browser/CoreBrowserTerminal.ts +1339 -0
- package/node_modules/@xterm/xterm/src/browser/Linkifier.ts +403 -0
- package/node_modules/@xterm/xterm/src/browser/LocalizableStrings.ts +23 -0
- package/node_modules/@xterm/xterm/src/browser/OscLinkProvider.ts +129 -0
- package/node_modules/@xterm/xterm/src/browser/RenderDebouncer.ts +84 -0
- package/node_modules/@xterm/xterm/src/browser/TimeBasedDebouncer.ts +86 -0
- package/node_modules/@xterm/xterm/src/browser/Types.ts +226 -0
- package/node_modules/@xterm/xterm/src/browser/Viewport.ts +192 -0
- package/node_modules/@xterm/xterm/src/browser/decorations/BufferDecorationRenderer.ts +139 -0
- package/node_modules/@xterm/xterm/src/browser/decorations/ColorZoneStore.ts +117 -0
- package/node_modules/@xterm/xterm/src/browser/decorations/OverviewRulerRenderer.ts +214 -0
- package/node_modules/@xterm/xterm/src/browser/input/CompositionHelper.ts +248 -0
- package/node_modules/@xterm/xterm/src/browser/input/Mouse.ts +54 -0
- package/node_modules/@xterm/xterm/src/browser/input/MoveToCell.ts +251 -0
- package/node_modules/@xterm/xterm/src/browser/public/Terminal.ts +275 -0
- package/node_modules/@xterm/xterm/src/browser/renderer/dom/DomRenderer.ts +542 -0
- package/node_modules/@xterm/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +546 -0
- package/node_modules/@xterm/xterm/src/browser/renderer/dom/WidthCache.ts +167 -0
- package/node_modules/@xterm/xterm/src/browser/renderer/shared/Constants.ts +6 -0
- package/node_modules/@xterm/xterm/src/browser/renderer/shared/RendererUtils.ts +95 -0
- package/node_modules/@xterm/xterm/src/browser/renderer/shared/SelectionRenderModel.ts +93 -0
- package/node_modules/@xterm/xterm/src/browser/renderer/shared/Types.ts +84 -0
- package/node_modules/@xterm/xterm/src/browser/selection/SelectionModel.ts +144 -0
- package/node_modules/@xterm/xterm/src/browser/selection/Types.ts +15 -0
- package/node_modules/@xterm/xterm/src/browser/services/CharSizeService.ts +127 -0
- package/node_modules/@xterm/xterm/src/browser/services/CharacterJoinerService.ts +339 -0
- package/node_modules/@xterm/xterm/src/browser/services/CoreBrowserService.ts +137 -0
- package/node_modules/@xterm/xterm/src/browser/services/LinkProviderService.ts +28 -0
- package/node_modules/@xterm/xterm/src/browser/services/MouseService.ts +46 -0
- package/node_modules/@xterm/xterm/src/browser/services/RenderService.ts +376 -0
- package/node_modules/@xterm/xterm/src/browser/services/SelectionService.ts +1039 -0
- package/node_modules/@xterm/xterm/src/browser/services/Services.ts +158 -0
- package/node_modules/@xterm/xterm/src/browser/services/ThemeService.ts +198 -0
- package/node_modules/@xterm/xterm/src/browser/shared/Constants.ts +8 -0
- package/node_modules/@xterm/xterm/src/common/CircularList.ts +241 -0
- package/node_modules/@xterm/xterm/src/common/Clone.ts +23 -0
- package/node_modules/@xterm/xterm/src/common/Color.ts +376 -0
- package/node_modules/@xterm/xterm/src/common/CoreTerminal.ts +283 -0
- package/node_modules/@xterm/xterm/src/common/InputHandler.ts +3495 -0
- package/node_modules/@xterm/xterm/src/common/MultiKeyMap.ts +42 -0
- package/node_modules/@xterm/xterm/src/common/Platform.ts +44 -0
- package/node_modules/@xterm/xterm/src/common/SortedList.ts +194 -0
- package/node_modules/@xterm/xterm/src/common/TaskQueue.ts +166 -0
- package/node_modules/@xterm/xterm/src/common/TypedArrayUtils.ts +17 -0
- package/node_modules/@xterm/xterm/src/common/Types.ts +552 -0
- package/node_modules/@xterm/xterm/src/common/WindowsMode.ts +27 -0
- package/node_modules/@xterm/xterm/src/common/buffer/AttributeData.ts +211 -0
- package/node_modules/@xterm/xterm/src/common/buffer/Buffer.ts +662 -0
- package/node_modules/@xterm/xterm/src/common/buffer/BufferLine.ts +551 -0
- package/node_modules/@xterm/xterm/src/common/buffer/BufferRange.ts +13 -0
- package/node_modules/@xterm/xterm/src/common/buffer/BufferReflow.ts +226 -0
- package/node_modules/@xterm/xterm/src/common/buffer/BufferSet.ts +134 -0
- package/node_modules/@xterm/xterm/src/common/buffer/CellData.ts +94 -0
- package/node_modules/@xterm/xterm/src/common/buffer/Constants.ts +157 -0
- package/node_modules/@xterm/xterm/src/common/buffer/Marker.ts +43 -0
- package/node_modules/@xterm/xterm/src/common/buffer/Types.ts +52 -0
- package/node_modules/@xterm/xterm/src/common/data/Charsets.ts +256 -0
- package/node_modules/@xterm/xterm/src/common/data/EscapeSequences.ts +153 -0
- package/node_modules/@xterm/xterm/src/common/input/Keyboard.ts +373 -0
- package/node_modules/@xterm/xterm/src/common/input/TextDecoder.ts +346 -0
- package/node_modules/@xterm/xterm/src/common/input/UnicodeV6.ts +145 -0
- package/node_modules/@xterm/xterm/src/common/input/WriteBuffer.ts +247 -0
- package/node_modules/@xterm/xterm/src/common/input/XParseColor.ts +80 -0
- package/node_modules/@xterm/xterm/src/common/parser/Constants.ts +58 -0
- package/node_modules/@xterm/xterm/src/common/parser/DcsParser.ts +192 -0
- package/node_modules/@xterm/xterm/src/common/parser/EscapeSequenceParser.ts +792 -0
- package/node_modules/@xterm/xterm/src/common/parser/OscParser.ts +238 -0
- package/node_modules/@xterm/xterm/src/common/parser/Params.ts +229 -0
- package/node_modules/@xterm/xterm/src/common/parser/Types.ts +275 -0
- package/node_modules/@xterm/xterm/src/common/public/AddonManager.ts +53 -0
- package/node_modules/@xterm/xterm/src/common/public/BufferApiView.ts +35 -0
- package/node_modules/@xterm/xterm/src/common/public/BufferLineApiView.ts +29 -0
- package/node_modules/@xterm/xterm/src/common/public/BufferNamespaceApi.ts +36 -0
- package/node_modules/@xterm/xterm/src/common/public/ParserApi.ts +37 -0
- package/node_modules/@xterm/xterm/src/common/public/UnicodeApi.ts +27 -0
- package/node_modules/@xterm/xterm/src/common/services/BufferService.ts +154 -0
- package/node_modules/@xterm/xterm/src/common/services/CharsetService.ts +34 -0
- package/node_modules/@xterm/xterm/src/common/services/CoreMouseService.ts +365 -0
- package/node_modules/@xterm/xterm/src/common/services/CoreService.ts +92 -0
- package/node_modules/@xterm/xterm/src/common/services/DecorationService.ts +140 -0
- package/node_modules/@xterm/xterm/src/common/services/InstantiationService.ts +85 -0
- package/node_modules/@xterm/xterm/src/common/services/LogService.ts +124 -0
- package/node_modules/@xterm/xterm/src/common/services/OptionsService.ts +212 -0
- package/node_modules/@xterm/xterm/src/common/services/OscLinkService.ts +115 -0
- package/node_modules/@xterm/xterm/src/common/services/ServiceRegistry.ts +49 -0
- package/node_modules/@xterm/xterm/src/common/services/Services.ts +396 -0
- package/node_modules/@xterm/xterm/src/common/services/UnicodeService.ts +111 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/browser.ts +141 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/canIUse.ts +49 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/dom.ts +2369 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/fastDomNode.ts +316 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/iframe.ts +135 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/keyboardEvent.ts +213 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/mouseEvent.ts +229 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/touch.ts +372 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/ui/widget.ts +57 -0
- package/node_modules/@xterm/xterm/src/vs/base/browser/window.ts +14 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/arrays.ts +887 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/arraysFind.ts +202 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/assert.ts +71 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/async.ts +1992 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/cancellation.ts +148 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/charCode.ts +450 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/collections.ts +140 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/decorators.ts +130 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/equals.ts +146 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/errors.ts +303 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/event.ts +1778 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/functional.ts +32 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/hash.ts +316 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/iterator.ts +159 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/keyCodes.ts +526 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/keybindings.ts +284 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/lazy.ts +47 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/lifecycle.ts +801 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/linkedList.ts +142 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/map.ts +202 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/numbers.ts +98 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observable.ts +76 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/api.ts +31 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/autorun.ts +281 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/base.ts +489 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/debugName.ts +145 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/derived.ts +428 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/logging.ts +328 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/promise.ts +209 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/observableInternal/utils.ts +610 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/platform.ts +281 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/scrollable.ts +522 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/sequence.ts +34 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/stopwatch.ts +43 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/strings.ts +557 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/symbols.ts +9 -0
- package/node_modules/@xterm/xterm/src/vs/base/common/uint.ts +59 -0
- package/node_modules/@xterm/xterm/src/vs/patches/nls.ts +90 -0
- package/node_modules/@xterm/xterm/src/vs/typings/base-common.d.ts +20 -0
- package/node_modules/@xterm/xterm/src/vs/typings/require.d.ts +42 -0
- package/node_modules/@xterm/xterm/src/vs/typings/vscode-globals-nls.d.ts +36 -0
- package/node_modules/@xterm/xterm/src/vs/typings/vscode-globals-product.d.ts +33 -0
- package/node_modules/@xterm/xterm/typings/xterm.d.ts +1957 -0
- package/package.json +1 -1
- package/packages/daemon/src/api.js +122 -1
- package/packages/daemon/src/index.js +25 -7
- package/packages/daemon/src/mimetypes.js +43 -0
- package/packages/daemon/src/terminal-pty.js +129 -0
- package/packages/gui/dist/assets/{index-Gfb8Zxy9.css → index-BhjOFLBc.css} +32 -1
- package/packages/gui/dist/assets/index-DeXW9EFU.js +153 -0
- package/packages/gui/dist/index.html +2 -2
- package/packages/gui/package.json +3 -0
- package/packages/gui/src/components/EditorTabs.jsx +1 -1
- package/packages/gui/src/components/FileTree.jsx +308 -23
- package/packages/gui/src/components/MediaViewer.jsx +104 -0
- package/packages/gui/src/components/Terminal.jsx +154 -0
- package/packages/gui/src/stores/groove.js +131 -2
- package/packages/gui/src/views/FileEditor.jsx +104 -36
- package/node_modules/@groove-dev/gui/dist/assets/index-Dxg9hdf3.js +0 -103
- package/packages/gui/dist/assets/index-Dxg9hdf3.js +0 -103
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
const RENDER_DEBOUNCE_THRESHOLD_MS = 1000; // 1 Second
|
|
7
|
+
|
|
8
|
+
import { IRenderDebouncer } from 'browser/Types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Debounces calls to update screen readers to update at most once configurable interval of time.
|
|
12
|
+
*/
|
|
13
|
+
export class TimeBasedDebouncer implements IRenderDebouncer {
|
|
14
|
+
private _rowStart: number | undefined;
|
|
15
|
+
private _rowEnd: number | undefined;
|
|
16
|
+
private _rowCount: number | undefined;
|
|
17
|
+
|
|
18
|
+
// The last moment that the Terminal was refreshed at
|
|
19
|
+
private _lastRefreshMs = 0;
|
|
20
|
+
// Whether a trailing refresh should be triggered due to a refresh request that was throttled
|
|
21
|
+
private _additionalRefreshRequested = false;
|
|
22
|
+
|
|
23
|
+
private _refreshTimeoutID: number | undefined;
|
|
24
|
+
|
|
25
|
+
constructor(
|
|
26
|
+
private _renderCallback: (start: number, end: number) => void,
|
|
27
|
+
private readonly _debounceThresholdMS = RENDER_DEBOUNCE_THRESHOLD_MS
|
|
28
|
+
) {
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public dispose(): void {
|
|
32
|
+
if (this._refreshTimeoutID) {
|
|
33
|
+
clearTimeout(this._refreshTimeoutID);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
public refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void {
|
|
38
|
+
this._rowCount = rowCount;
|
|
39
|
+
// Get the min/max row start/end for the arg values
|
|
40
|
+
rowStart = rowStart !== undefined ? rowStart : 0;
|
|
41
|
+
rowEnd = rowEnd !== undefined ? rowEnd : this._rowCount - 1;
|
|
42
|
+
// Set the properties to the updated values
|
|
43
|
+
this._rowStart = this._rowStart !== undefined ? Math.min(this._rowStart, rowStart) : rowStart;
|
|
44
|
+
this._rowEnd = this._rowEnd !== undefined ? Math.max(this._rowEnd, rowEnd) : rowEnd;
|
|
45
|
+
|
|
46
|
+
// Only refresh if the time since last refresh is above a threshold, otherwise wait for
|
|
47
|
+
// enough time to pass before refreshing again.
|
|
48
|
+
const refreshRequestTime: number = performance.now();
|
|
49
|
+
if (refreshRequestTime - this._lastRefreshMs >= this._debounceThresholdMS) {
|
|
50
|
+
// Enough time has lapsed since the last refresh; refresh immediately
|
|
51
|
+
this._lastRefreshMs = refreshRequestTime;
|
|
52
|
+
this._innerRefresh();
|
|
53
|
+
} else if (!this._additionalRefreshRequested) {
|
|
54
|
+
// This is the first additional request throttled; set up trailing refresh
|
|
55
|
+
const elapsed = refreshRequestTime - this._lastRefreshMs;
|
|
56
|
+
const waitPeriodBeforeTrailingRefresh = this._debounceThresholdMS - elapsed;
|
|
57
|
+
this._additionalRefreshRequested = true;
|
|
58
|
+
|
|
59
|
+
this._refreshTimeoutID = window.setTimeout(() => {
|
|
60
|
+
this._lastRefreshMs = performance.now();
|
|
61
|
+
this._innerRefresh();
|
|
62
|
+
this._additionalRefreshRequested = false;
|
|
63
|
+
this._refreshTimeoutID = undefined; // No longer need to clear the timeout
|
|
64
|
+
}, waitPeriodBeforeTrailingRefresh);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private _innerRefresh(): void {
|
|
69
|
+
// Make sure values are set
|
|
70
|
+
if (this._rowStart === undefined || this._rowEnd === undefined || this._rowCount === undefined) {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Clamp values
|
|
75
|
+
const start = Math.max(this._rowStart, 0);
|
|
76
|
+
const end = Math.min(this._rowEnd, this._rowCount - 1);
|
|
77
|
+
|
|
78
|
+
// Reset debouncer (this happens before render callback as the render could trigger it again)
|
|
79
|
+
this._rowStart = undefined;
|
|
80
|
+
this._rowEnd = undefined;
|
|
81
|
+
|
|
82
|
+
// Run render callback
|
|
83
|
+
this._renderCallback(start, end);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { CharData, IColor, ICoreTerminal, ITerminalOptions } from 'common/Types';
|
|
7
|
+
import { IBuffer } from 'common/buffer/Types';
|
|
8
|
+
import { IDisposable, Terminal as ITerminalApi } from '@xterm/xterm';
|
|
9
|
+
import { channels, css } from 'common/Color';
|
|
10
|
+
import type { Event } from 'vs/base/common/event';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A portion of the public API that are implemented identially internally and simply passed through.
|
|
14
|
+
*/
|
|
15
|
+
type InternalPassthroughApis = Omit<ITerminalApi, 'buffer' | 'parser' | 'unicode' | 'modes' | 'writeln' | 'loadAddon'>;
|
|
16
|
+
|
|
17
|
+
export interface ITerminal extends InternalPassthroughApis, ICoreTerminal {
|
|
18
|
+
screenElement: HTMLElement | undefined;
|
|
19
|
+
browser: IBrowser;
|
|
20
|
+
buffer: IBuffer;
|
|
21
|
+
linkifier: ILinkifier2 | undefined;
|
|
22
|
+
options: Required<ITerminalOptions>;
|
|
23
|
+
|
|
24
|
+
onBlur: Event<void>;
|
|
25
|
+
onFocus: Event<void>;
|
|
26
|
+
onA11yChar: Event<string>;
|
|
27
|
+
onA11yTab: Event<number>;
|
|
28
|
+
onWillOpen: Event<HTMLElement>;
|
|
29
|
+
|
|
30
|
+
cancel(ev: MouseEvent | WheelEvent | KeyboardEvent | InputEvent, force?: boolean): boolean | void;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
|
|
34
|
+
export type CustomWheelEventHandler = (event: WheelEvent) => boolean;
|
|
35
|
+
|
|
36
|
+
export type LineData = CharData[];
|
|
37
|
+
|
|
38
|
+
export interface ICompositionHelper {
|
|
39
|
+
readonly isComposing: boolean;
|
|
40
|
+
compositionstart(): void;
|
|
41
|
+
compositionupdate(ev: CompositionEvent): void;
|
|
42
|
+
compositionend(): void;
|
|
43
|
+
updateCompositionElements(dontRecurse?: boolean): void;
|
|
44
|
+
keydown(ev: KeyboardEvent): boolean;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export interface IBrowser {
|
|
48
|
+
isNode: boolean;
|
|
49
|
+
userAgent: string;
|
|
50
|
+
platform: string;
|
|
51
|
+
isFirefox: boolean;
|
|
52
|
+
isMac: boolean;
|
|
53
|
+
isIpad: boolean;
|
|
54
|
+
isIphone: boolean;
|
|
55
|
+
isWindows: boolean;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface IColorSet {
|
|
59
|
+
foreground: IColor;
|
|
60
|
+
background: IColor;
|
|
61
|
+
cursor: IColor;
|
|
62
|
+
cursorAccent: IColor;
|
|
63
|
+
selectionForeground: IColor | undefined;
|
|
64
|
+
selectionBackgroundTransparent: IColor;
|
|
65
|
+
/** The selection blended on top of background. */
|
|
66
|
+
selectionBackgroundOpaque: IColor;
|
|
67
|
+
selectionInactiveBackgroundTransparent: IColor;
|
|
68
|
+
selectionInactiveBackgroundOpaque: IColor;
|
|
69
|
+
scrollbarSliderBackground: IColor;
|
|
70
|
+
scrollbarSliderHoverBackground: IColor;
|
|
71
|
+
scrollbarSliderActiveBackground: IColor;
|
|
72
|
+
overviewRulerBorder: IColor;
|
|
73
|
+
ansi: IColor[];
|
|
74
|
+
/** Maps original colors to colors that respect minimum contrast ratio. */
|
|
75
|
+
contrastCache: IColorContrastCache;
|
|
76
|
+
/** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */
|
|
77
|
+
halfContrastCache: IColorContrastCache;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export type ReadonlyColorSet = Readonly<Omit<IColorSet, 'ansi'>> & { ansi: Readonly<Pick<IColorSet, 'ansi'>['ansi']> };
|
|
81
|
+
|
|
82
|
+
export interface IColorContrastCache {
|
|
83
|
+
clear(): void;
|
|
84
|
+
setCss(bg: number, fg: number, value: string | null): void;
|
|
85
|
+
getCss(bg: number, fg: number): string | null | undefined;
|
|
86
|
+
setColor(bg: number, fg: number, value: IColor | null): void;
|
|
87
|
+
getColor(bg: number, fg: number): IColor | null | undefined;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export interface IPartialColorSet {
|
|
91
|
+
foreground: IColor;
|
|
92
|
+
background: IColor;
|
|
93
|
+
cursor?: IColor;
|
|
94
|
+
cursorAccent?: IColor;
|
|
95
|
+
selectionBackground?: IColor;
|
|
96
|
+
ansi: IColor[];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export interface IViewport extends IDisposable {
|
|
100
|
+
scrollBarWidth: number;
|
|
101
|
+
readonly onRequestScrollLines: Event<{ amount: number, suppressScrollEvent: boolean }>;
|
|
102
|
+
syncScrollArea(immediate?: boolean, force?: boolean): void;
|
|
103
|
+
getLinesScrolled(ev: WheelEvent): number;
|
|
104
|
+
getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };
|
|
105
|
+
handleWheel(ev: WheelEvent): boolean;
|
|
106
|
+
handleTouchStart(ev: TouchEvent): void;
|
|
107
|
+
handleTouchMove(ev: TouchEvent): boolean;
|
|
108
|
+
scrollLines(disp: number): void; // todo api name?
|
|
109
|
+
reset(): void;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface ILinkifierEvent {
|
|
113
|
+
x1: number;
|
|
114
|
+
y1: number;
|
|
115
|
+
x2: number;
|
|
116
|
+
y2: number;
|
|
117
|
+
cols: number;
|
|
118
|
+
fg: number | undefined;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
interface ILinkState {
|
|
122
|
+
decorations: ILinkDecorations;
|
|
123
|
+
isHovered: boolean;
|
|
124
|
+
}
|
|
125
|
+
export interface ILinkWithState {
|
|
126
|
+
link: ILink;
|
|
127
|
+
state?: ILinkState;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export interface ILinkifier2 extends IDisposable {
|
|
131
|
+
onShowLinkUnderline: Event<ILinkifierEvent>;
|
|
132
|
+
onHideLinkUnderline: Event<ILinkifierEvent>;
|
|
133
|
+
readonly currentLink: ILinkWithState | undefined;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export interface ILink {
|
|
137
|
+
range: IBufferRange;
|
|
138
|
+
text: string;
|
|
139
|
+
decorations?: ILinkDecorations;
|
|
140
|
+
activate(event: MouseEvent, text: string): void;
|
|
141
|
+
hover?(event: MouseEvent, text: string): void;
|
|
142
|
+
leave?(event: MouseEvent, text: string): void;
|
|
143
|
+
dispose?(): void;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface ILinkDecorations {
|
|
147
|
+
pointerCursor: boolean;
|
|
148
|
+
underline: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface IBufferRange {
|
|
152
|
+
start: IBufferCellPosition;
|
|
153
|
+
end: IBufferCellPosition;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
export interface IBufferCellPosition {
|
|
157
|
+
x: number;
|
|
158
|
+
y: number;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export type CharacterJoinerHandler = (text: string) => [number, number][];
|
|
162
|
+
|
|
163
|
+
export interface ICharacterJoiner {
|
|
164
|
+
id: number;
|
|
165
|
+
handler: CharacterJoinerHandler;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
export interface IRenderDebouncer extends IDisposable {
|
|
169
|
+
refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export interface IRenderDebouncerWithCallback extends IRenderDebouncer {
|
|
173
|
+
addRefreshCallback(callback: FrameRequestCallback): number;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
export interface IBufferElementProvider {
|
|
177
|
+
provideBufferElements(): DocumentFragment | HTMLElement;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// An IIFE to generate DEFAULT_ANSI_COLORS.
|
|
181
|
+
export const DEFAULT_ANSI_COLORS = Object.freeze((() => {
|
|
182
|
+
const colors = [
|
|
183
|
+
// dark:
|
|
184
|
+
css.toColor('#2e3436'),
|
|
185
|
+
css.toColor('#cc0000'),
|
|
186
|
+
css.toColor('#4e9a06'),
|
|
187
|
+
css.toColor('#c4a000'),
|
|
188
|
+
css.toColor('#3465a4'),
|
|
189
|
+
css.toColor('#75507b'),
|
|
190
|
+
css.toColor('#06989a'),
|
|
191
|
+
css.toColor('#d3d7cf'),
|
|
192
|
+
// bright:
|
|
193
|
+
css.toColor('#555753'),
|
|
194
|
+
css.toColor('#ef2929'),
|
|
195
|
+
css.toColor('#8ae234'),
|
|
196
|
+
css.toColor('#fce94f'),
|
|
197
|
+
css.toColor('#729fcf'),
|
|
198
|
+
css.toColor('#ad7fa8'),
|
|
199
|
+
css.toColor('#34e2e2'),
|
|
200
|
+
css.toColor('#eeeeec')
|
|
201
|
+
];
|
|
202
|
+
|
|
203
|
+
// Fill in the remaining 240 ANSI colors.
|
|
204
|
+
// Generate colors (16-231)
|
|
205
|
+
const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];
|
|
206
|
+
for (let i = 0; i < 216; i++) {
|
|
207
|
+
const r = v[(i / 36) % 6 | 0];
|
|
208
|
+
const g = v[(i / 6) % 6 | 0];
|
|
209
|
+
const b = v[i % 6];
|
|
210
|
+
colors.push({
|
|
211
|
+
css: channels.toCss(r, g, b),
|
|
212
|
+
rgba: channels.toRgba(r, g, b)
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Generate greys (232-255)
|
|
217
|
+
for (let i = 0; i < 24; i++) {
|
|
218
|
+
const c = 8 + i * 10;
|
|
219
|
+
colors.push({
|
|
220
|
+
css: channels.toCss(c, c, c),
|
|
221
|
+
rgba: channels.toRgba(c, c, c)
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return colors;
|
|
226
|
+
})());
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2024 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
|
|
7
|
+
import { ViewportConstants } from 'browser/shared/Constants';
|
|
8
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
9
|
+
import { IBufferService, ICoreMouseService, IOptionsService } from 'common/services/Services';
|
|
10
|
+
import { CoreMouseEventType } from 'common/Types';
|
|
11
|
+
import { scheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
|
|
12
|
+
import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollableElement';
|
|
13
|
+
import type { ScrollableElementChangeOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
|
|
14
|
+
import { Emitter, Event } from 'vs/base/common/event';
|
|
15
|
+
import { Scrollable, ScrollbarVisibility, type ScrollEvent } from 'vs/base/common/scrollable';
|
|
16
|
+
|
|
17
|
+
export class Viewport extends Disposable {
|
|
18
|
+
|
|
19
|
+
protected _onRequestScrollLines = this._register(new Emitter<number>());
|
|
20
|
+
public readonly onRequestScrollLines = this._onRequestScrollLines.event;
|
|
21
|
+
|
|
22
|
+
private _scrollableElement: SmoothScrollableElement;
|
|
23
|
+
private _styleElement: HTMLStyleElement;
|
|
24
|
+
|
|
25
|
+
private _queuedAnimationFrame?: number;
|
|
26
|
+
private _latestYDisp?: number;
|
|
27
|
+
private _isSyncing: boolean = false;
|
|
28
|
+
private _isHandlingScroll: boolean = false;
|
|
29
|
+
private _suppressOnScrollHandler: boolean = false;
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
element: HTMLElement,
|
|
33
|
+
screenElement: HTMLElement,
|
|
34
|
+
@IBufferService private readonly _bufferService: IBufferService,
|
|
35
|
+
@ICoreBrowserService coreBrowserService: ICoreBrowserService,
|
|
36
|
+
@ICoreMouseService coreMouseService: ICoreMouseService,
|
|
37
|
+
@IThemeService themeService: IThemeService,
|
|
38
|
+
@IOptionsService private readonly _optionsService: IOptionsService,
|
|
39
|
+
@IRenderService private readonly _renderService: IRenderService
|
|
40
|
+
) {
|
|
41
|
+
super();
|
|
42
|
+
|
|
43
|
+
const scrollable = this._register(new Scrollable({
|
|
44
|
+
forceIntegerValues: false,
|
|
45
|
+
smoothScrollDuration: this._optionsService.rawOptions.smoothScrollDuration,
|
|
46
|
+
// This is used over `IRenderService.addRefreshCallback` since it can be canceled
|
|
47
|
+
scheduleAtNextAnimationFrame: cb => scheduleAtNextAnimationFrame(coreBrowserService.window, cb)
|
|
48
|
+
}));
|
|
49
|
+
this._register(this._optionsService.onSpecificOptionChange('smoothScrollDuration', () => {
|
|
50
|
+
scrollable.setSmoothScrollDuration(this._optionsService.rawOptions.smoothScrollDuration);
|
|
51
|
+
}));
|
|
52
|
+
|
|
53
|
+
this._scrollableElement = this._register(new SmoothScrollableElement(screenElement, {
|
|
54
|
+
vertical: ScrollbarVisibility.Auto,
|
|
55
|
+
horizontal: ScrollbarVisibility.Hidden,
|
|
56
|
+
useShadows: false,
|
|
57
|
+
mouseWheelSmoothScroll: true,
|
|
58
|
+
...this._getChangeOptions()
|
|
59
|
+
}, scrollable));
|
|
60
|
+
this._register(this._optionsService.onMultipleOptionChange([
|
|
61
|
+
'scrollSensitivity',
|
|
62
|
+
'fastScrollSensitivity',
|
|
63
|
+
'overviewRuler'
|
|
64
|
+
], () => this._scrollableElement.updateOptions(this._getChangeOptions())));
|
|
65
|
+
// Don't handle mouse wheel if wheel events are supported by the current mouse prototcol
|
|
66
|
+
this._register(coreMouseService.onProtocolChange(type => {
|
|
67
|
+
this._scrollableElement.updateOptions({
|
|
68
|
+
handleMouseWheel: !(type & CoreMouseEventType.WHEEL)
|
|
69
|
+
});
|
|
70
|
+
}));
|
|
71
|
+
|
|
72
|
+
this._scrollableElement.setScrollDimensions({ height: 0, scrollHeight: 0 });
|
|
73
|
+
this._register(Event.runAndSubscribe(themeService.onChangeColors, () => {
|
|
74
|
+
this._scrollableElement.getDomNode().style.backgroundColor = themeService.colors.background.css;
|
|
75
|
+
}));
|
|
76
|
+
element.appendChild(this._scrollableElement.getDomNode());
|
|
77
|
+
this._register(toDisposable(() => this._scrollableElement.getDomNode().remove()));
|
|
78
|
+
|
|
79
|
+
this._styleElement = coreBrowserService.mainDocument.createElement('style');
|
|
80
|
+
screenElement.appendChild(this._styleElement);
|
|
81
|
+
this._register(toDisposable(() => this._styleElement.remove()));
|
|
82
|
+
this._register(Event.runAndSubscribe(themeService.onChangeColors, () => {
|
|
83
|
+
this._styleElement.textContent = [
|
|
84
|
+
`.xterm .xterm-scrollable-element > .scrollbar > .slider {`,
|
|
85
|
+
` background: ${themeService.colors.scrollbarSliderBackground.css};`,
|
|
86
|
+
`}`,
|
|
87
|
+
`.xterm .xterm-scrollable-element > .scrollbar > .slider:hover {`,
|
|
88
|
+
` background: ${themeService.colors.scrollbarSliderHoverBackground.css};`,
|
|
89
|
+
`}`,
|
|
90
|
+
`.xterm .xterm-scrollable-element > .scrollbar > .slider.active {`,
|
|
91
|
+
` background: ${themeService.colors.scrollbarSliderActiveBackground.css};`,
|
|
92
|
+
`}`
|
|
93
|
+
].join('\n');
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
this._register(this._bufferService.onResize(() => this.queueSync()));
|
|
97
|
+
this._register(this._bufferService.buffers.onBufferActivate(() => {
|
|
98
|
+
// Reset _latestYDisp when switching buffers to prevent stale scroll position
|
|
99
|
+
// from alt buffer contaminating normal buffer scroll position
|
|
100
|
+
this._latestYDisp = undefined;
|
|
101
|
+
this.queueSync();
|
|
102
|
+
}));
|
|
103
|
+
this._register(this._bufferService.onScroll(() => this._sync()));
|
|
104
|
+
|
|
105
|
+
this._register(this._scrollableElement.onScroll(e => this._handleScroll(e)));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
public scrollLines(disp: number): void {
|
|
109
|
+
const pos = this._scrollableElement.getScrollPosition();
|
|
110
|
+
this._scrollableElement.setScrollPosition({
|
|
111
|
+
reuseAnimation: true,
|
|
112
|
+
scrollTop: pos.scrollTop + disp * this._renderService.dimensions.css.cell.height
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
public scrollToLine(line: number, disableSmoothScroll?: boolean): void {
|
|
117
|
+
if (disableSmoothScroll) {
|
|
118
|
+
this._latestYDisp = line;
|
|
119
|
+
}
|
|
120
|
+
this._scrollableElement.setScrollPosition({
|
|
121
|
+
reuseAnimation: !disableSmoothScroll,
|
|
122
|
+
scrollTop: line * this._renderService.dimensions.css.cell.height
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
private _getChangeOptions(): ScrollableElementChangeOptions {
|
|
127
|
+
return {
|
|
128
|
+
mouseWheelScrollSensitivity: this._optionsService.rawOptions.scrollSensitivity,
|
|
129
|
+
fastScrollSensitivity: this._optionsService.rawOptions.fastScrollSensitivity,
|
|
130
|
+
verticalScrollbarSize: this._optionsService.rawOptions.overviewRuler?.width || ViewportConstants.DEFAULT_SCROLL_BAR_WIDTH
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
public queueSync(ydisp?: number): void {
|
|
135
|
+
// Update state
|
|
136
|
+
if (ydisp !== undefined) {
|
|
137
|
+
this._latestYDisp = ydisp;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Don't queue more than one callback
|
|
141
|
+
if (this._queuedAnimationFrame !== undefined) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
this._queuedAnimationFrame = this._renderService.addRefreshCallback(() => {
|
|
145
|
+
this._queuedAnimationFrame = undefined;
|
|
146
|
+
this._sync(this._latestYDisp);
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private _sync(ydisp: number = this._bufferService.buffer.ydisp): void {
|
|
151
|
+
if (!this._renderService || this._isSyncing) {
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
this._isSyncing = true;
|
|
155
|
+
|
|
156
|
+
// Ignore any onScroll event that happens as a result of dimensions changing as this should
|
|
157
|
+
// never cause a scrollLines call, only setScrollPosition can do that.
|
|
158
|
+
this._suppressOnScrollHandler = true;
|
|
159
|
+
this._scrollableElement.setScrollDimensions({
|
|
160
|
+
height: this._renderService.dimensions.css.canvas.height,
|
|
161
|
+
scrollHeight: this._renderService.dimensions.css.cell.height * this._bufferService.buffer.lines.length
|
|
162
|
+
});
|
|
163
|
+
this._suppressOnScrollHandler = false;
|
|
164
|
+
|
|
165
|
+
// If ydisp has been changed by some other component (input/buffer), then stop animating smooth
|
|
166
|
+
// scroll and scroll there immediately.
|
|
167
|
+
if (ydisp !== this._latestYDisp) {
|
|
168
|
+
this._scrollableElement.setScrollPosition({
|
|
169
|
+
scrollTop: ydisp * this._renderService.dimensions.css.cell.height
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
this._isSyncing = false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private _handleScroll(e: ScrollEvent): void {
|
|
177
|
+
if (!this._renderService) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (this._isHandlingScroll || this._suppressOnScrollHandler) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
this._isHandlingScroll = true;
|
|
184
|
+
const newRow = Math.round(e.scrollTop / this._renderService.dimensions.css.cell.height);
|
|
185
|
+
const diff = newRow - this._bufferService.buffer.ydisp;
|
|
186
|
+
if (diff !== 0) {
|
|
187
|
+
this._latestYDisp = newRow;
|
|
188
|
+
this._onRequestScrollLines.fire(diff);
|
|
189
|
+
}
|
|
190
|
+
this._isHandlingScroll = false;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
@@ -0,0 +1,139 @@
|
|
|
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 { ICoreBrowserService, IRenderService } from 'browser/services/Services';
|
|
7
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
8
|
+
import { IBufferService, IDecorationService, IInternalDecoration } from 'common/services/Services';
|
|
9
|
+
|
|
10
|
+
export class BufferDecorationRenderer extends Disposable {
|
|
11
|
+
private readonly _container: HTMLElement;
|
|
12
|
+
private readonly _decorationElements: Map<IInternalDecoration, HTMLElement> = new Map();
|
|
13
|
+
|
|
14
|
+
private _animationFrame: number | undefined;
|
|
15
|
+
private _altBufferIsActive: boolean = false;
|
|
16
|
+
private _dimensionsChanged: boolean = false;
|
|
17
|
+
|
|
18
|
+
constructor(
|
|
19
|
+
private readonly _screenElement: HTMLElement,
|
|
20
|
+
@IBufferService private readonly _bufferService: IBufferService,
|
|
21
|
+
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,
|
|
22
|
+
@IDecorationService private readonly _decorationService: IDecorationService,
|
|
23
|
+
@IRenderService private readonly _renderService: IRenderService
|
|
24
|
+
) {
|
|
25
|
+
super();
|
|
26
|
+
|
|
27
|
+
this._container = document.createElement('div');
|
|
28
|
+
this._container.classList.add('xterm-decoration-container');
|
|
29
|
+
this._screenElement.appendChild(this._container);
|
|
30
|
+
|
|
31
|
+
this._register(this._renderService.onRenderedViewportChange(() => this._doRefreshDecorations()));
|
|
32
|
+
this._register(this._renderService.onDimensionsChange(() => {
|
|
33
|
+
this._dimensionsChanged = true;
|
|
34
|
+
this._queueRefresh();
|
|
35
|
+
}));
|
|
36
|
+
this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh()));
|
|
37
|
+
this._register(this._bufferService.buffers.onBufferActivate(() => {
|
|
38
|
+
this._altBufferIsActive = this._bufferService.buffer === this._bufferService.buffers.alt;
|
|
39
|
+
}));
|
|
40
|
+
this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh()));
|
|
41
|
+
this._register(this._decorationService.onDecorationRemoved(decoration => this._removeDecoration(decoration)));
|
|
42
|
+
this._register(toDisposable(() => {
|
|
43
|
+
this._container.remove();
|
|
44
|
+
this._decorationElements.clear();
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
private _queueRefresh(): void {
|
|
49
|
+
if (this._animationFrame !== undefined) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
this._animationFrame = this._renderService.addRefreshCallback(() => {
|
|
53
|
+
this._doRefreshDecorations();
|
|
54
|
+
this._animationFrame = undefined;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private _doRefreshDecorations(): void {
|
|
59
|
+
for (const decoration of this._decorationService.decorations) {
|
|
60
|
+
this._renderDecoration(decoration);
|
|
61
|
+
}
|
|
62
|
+
this._dimensionsChanged = false;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
private _renderDecoration(decoration: IInternalDecoration): void {
|
|
66
|
+
this._refreshStyle(decoration);
|
|
67
|
+
if (this._dimensionsChanged) {
|
|
68
|
+
this._refreshXPosition(decoration);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private _createElement(decoration: IInternalDecoration): HTMLElement {
|
|
73
|
+
const element = this._coreBrowserService.mainDocument.createElement('div');
|
|
74
|
+
element.classList.add('xterm-decoration');
|
|
75
|
+
element.classList.toggle('xterm-decoration-top-layer', decoration?.options?.layer === 'top');
|
|
76
|
+
element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;
|
|
77
|
+
element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;
|
|
78
|
+
element.style.top = `${(decoration.marker.line - this._bufferService.buffers.active.ydisp) * this._renderService.dimensions.css.cell.height}px`;
|
|
79
|
+
element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;
|
|
80
|
+
|
|
81
|
+
const x = decoration.options.x ?? 0;
|
|
82
|
+
if (x && x > this._bufferService.cols) {
|
|
83
|
+
// exceeded the container width, so hide
|
|
84
|
+
element.style.display = 'none';
|
|
85
|
+
}
|
|
86
|
+
this._refreshXPosition(decoration, element);
|
|
87
|
+
|
|
88
|
+
return element;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private _refreshStyle(decoration: IInternalDecoration): void {
|
|
92
|
+
const line = decoration.marker.line - this._bufferService.buffers.active.ydisp;
|
|
93
|
+
if (line < 0 || line >= this._bufferService.rows) {
|
|
94
|
+
// outside of viewport
|
|
95
|
+
if (decoration.element) {
|
|
96
|
+
decoration.element.style.display = 'none';
|
|
97
|
+
decoration.onRenderEmitter.fire(decoration.element);
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
let element = this._decorationElements.get(decoration);
|
|
101
|
+
if (!element) {
|
|
102
|
+
element = this._createElement(decoration);
|
|
103
|
+
decoration.element = element;
|
|
104
|
+
this._decorationElements.set(decoration, element);
|
|
105
|
+
this._container.appendChild(element);
|
|
106
|
+
decoration.onDispose(() => {
|
|
107
|
+
this._decorationElements.delete(decoration);
|
|
108
|
+
element!.remove();
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
element.style.display = this._altBufferIsActive ? 'none' : 'block';
|
|
112
|
+
if (!this._altBufferIsActive) {
|
|
113
|
+
element.style.width = `${Math.round((decoration.options.width || 1) * this._renderService.dimensions.css.cell.width)}px`;
|
|
114
|
+
element.style.height = `${(decoration.options.height || 1) * this._renderService.dimensions.css.cell.height}px`;
|
|
115
|
+
element.style.top = `${line * this._renderService.dimensions.css.cell.height}px`;
|
|
116
|
+
element.style.lineHeight = `${this._renderService.dimensions.css.cell.height}px`;
|
|
117
|
+
}
|
|
118
|
+
decoration.onRenderEmitter.fire(element);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
private _refreshXPosition(decoration: IInternalDecoration, element: HTMLElement | undefined = decoration.element): void {
|
|
123
|
+
if (!element) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const x = decoration.options.x ?? 0;
|
|
127
|
+
if ((decoration.options.anchor || 'left') === 'right') {
|
|
128
|
+
element.style.right = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';
|
|
129
|
+
} else {
|
|
130
|
+
element.style.left = x ? `${x * this._renderService.dimensions.css.cell.width}px` : '';
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private _removeDecoration(decoration: IInternalDecoration): void {
|
|
135
|
+
this._decorationElements.get(decoration)?.remove();
|
|
136
|
+
this._decorationElements.delete(decoration);
|
|
137
|
+
decoration.dispose();
|
|
138
|
+
}
|
|
139
|
+
}
|