groove-dev 0.16.1 → 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/index.js +25 -7
- 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 +0 -14
- package/node_modules/@groove-dev/gui/src/components/Terminal.jsx +154 -0
- package/node_modules/@groove-dev/gui/src/views/FileEditor.jsx +100 -39
- 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/index.js +25 -7
- 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 +0 -14
- package/packages/gui/src/components/Terminal.jsx +154 -0
- package/packages/gui/src/views/FileEditor.jsx +100 -39
- package/node_modules/@groove-dev/gui/dist/assets/index-BQSznoq0.js +0 -103
- package/packages/gui/dist/assets/index-BQSznoq0.js +0 -103
|
@@ -0,0 +1,117 @@
|
|
|
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 { IInternalDecoration } from 'common/services/Services';
|
|
7
|
+
|
|
8
|
+
export interface IColorZoneStore {
|
|
9
|
+
readonly zones: IColorZone[];
|
|
10
|
+
clear(): void;
|
|
11
|
+
addDecoration(decoration: IInternalDecoration): void;
|
|
12
|
+
/**
|
|
13
|
+
* Sets the amount of padding in lines that will be added between zones, if new lines intersect
|
|
14
|
+
* the padding they will be merged into the same zone.
|
|
15
|
+
*/
|
|
16
|
+
setPadding(padding: { [position: string]: number }): void;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface IColorZone {
|
|
20
|
+
/** Color in a format supported by canvas' fillStyle. */
|
|
21
|
+
color: string;
|
|
22
|
+
position: 'full' | 'left' | 'center' | 'right' | undefined;
|
|
23
|
+
startBufferLine: number;
|
|
24
|
+
endBufferLine: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface IMinimalDecorationForColorZone {
|
|
28
|
+
marker: Pick<IInternalDecoration['marker'], 'line'>;
|
|
29
|
+
options: Pick<IInternalDecoration['options'], 'overviewRulerOptions'>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class ColorZoneStore implements IColorZoneStore {
|
|
33
|
+
private _zones: IColorZone[] = [];
|
|
34
|
+
|
|
35
|
+
// The zone pool is used to keep zone objects from being freed between clearing the color zone
|
|
36
|
+
// store and fetching the zones. This helps reduce GC pressure since the color zones are
|
|
37
|
+
// accumulated on potentially every scroll event.
|
|
38
|
+
private _zonePool: IColorZone[] = [];
|
|
39
|
+
private _zonePoolIndex = 0;
|
|
40
|
+
|
|
41
|
+
private _linePadding: { [position: string]: number } = {
|
|
42
|
+
full: 0,
|
|
43
|
+
left: 0,
|
|
44
|
+
center: 0,
|
|
45
|
+
right: 0
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
public get zones(): IColorZone[] {
|
|
49
|
+
// Trim the zone pool to free unused memory
|
|
50
|
+
this._zonePool.length = Math.min(this._zonePool.length, this._zones.length);
|
|
51
|
+
return this._zones;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
public clear(): void {
|
|
55
|
+
this._zones.length = 0;
|
|
56
|
+
this._zonePoolIndex = 0;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
public addDecoration(decoration: IMinimalDecorationForColorZone): void {
|
|
60
|
+
if (!decoration.options.overviewRulerOptions) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
for (const z of this._zones) {
|
|
64
|
+
if (z.color === decoration.options.overviewRulerOptions.color &&
|
|
65
|
+
z.position === decoration.options.overviewRulerOptions.position) {
|
|
66
|
+
if (this._lineIntersectsZone(z, decoration.marker.line)) {
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
if (this._lineAdjacentToZone(z, decoration.marker.line, decoration.options.overviewRulerOptions.position)) {
|
|
70
|
+
this._addLineToZone(z, decoration.marker.line);
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Create using zone pool if possible
|
|
76
|
+
if (this._zonePoolIndex < this._zonePool.length) {
|
|
77
|
+
this._zonePool[this._zonePoolIndex].color = decoration.options.overviewRulerOptions.color;
|
|
78
|
+
this._zonePool[this._zonePoolIndex].position = decoration.options.overviewRulerOptions.position;
|
|
79
|
+
this._zonePool[this._zonePoolIndex].startBufferLine = decoration.marker.line;
|
|
80
|
+
this._zonePool[this._zonePoolIndex].endBufferLine = decoration.marker.line;
|
|
81
|
+
this._zones.push(this._zonePool[this._zonePoolIndex++]);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
// Create
|
|
85
|
+
this._zones.push({
|
|
86
|
+
color: decoration.options.overviewRulerOptions.color,
|
|
87
|
+
position: decoration.options.overviewRulerOptions.position,
|
|
88
|
+
startBufferLine: decoration.marker.line,
|
|
89
|
+
endBufferLine: decoration.marker.line
|
|
90
|
+
});
|
|
91
|
+
this._zonePool.push(this._zones[this._zones.length - 1]);
|
|
92
|
+
this._zonePoolIndex++;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
public setPadding(padding: { [position: string]: number }): void {
|
|
96
|
+
this._linePadding = padding;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
private _lineIntersectsZone(zone: IColorZone, line: number): boolean {
|
|
100
|
+
return (
|
|
101
|
+
line >= zone.startBufferLine &&
|
|
102
|
+
line <= zone.endBufferLine
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
private _lineAdjacentToZone(zone: IColorZone, line: number, position: IColorZone['position']): boolean {
|
|
107
|
+
return (
|
|
108
|
+
(line >= zone.startBufferLine - this._linePadding[position || 'full']) &&
|
|
109
|
+
(line <= zone.endBufferLine + this._linePadding[position || 'full'])
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
private _addLineToZone(zone: IColorZone, line: number): void {
|
|
114
|
+
zone.startBufferLine = Math.min(zone.startBufferLine, line);
|
|
115
|
+
zone.endBufferLine = Math.max(zone.endBufferLine, line);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -0,0 +1,214 @@
|
|
|
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 { ColorZoneStore, IColorZone, IColorZoneStore } from 'browser/decorations/ColorZoneStore';
|
|
7
|
+
import { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
|
|
8
|
+
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
|
9
|
+
import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
|
|
10
|
+
|
|
11
|
+
const enum Constants {
|
|
12
|
+
OVERVIEW_RULER_BORDER_WIDTH = 1
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Helper objects to avoid excessive calculation and garbage collection during rendering. These are
|
|
16
|
+
// static values for each render and can be accessed using the decoration position as the key.
|
|
17
|
+
const drawHeight = {
|
|
18
|
+
full: 0,
|
|
19
|
+
left: 0,
|
|
20
|
+
center: 0,
|
|
21
|
+
right: 0
|
|
22
|
+
};
|
|
23
|
+
const drawWidth = {
|
|
24
|
+
full: 0,
|
|
25
|
+
left: 0,
|
|
26
|
+
center: 0,
|
|
27
|
+
right: 0
|
|
28
|
+
};
|
|
29
|
+
const drawX = {
|
|
30
|
+
full: 0,
|
|
31
|
+
left: 0,
|
|
32
|
+
center: 0,
|
|
33
|
+
right: 0
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export class OverviewRulerRenderer extends Disposable {
|
|
37
|
+
private readonly _canvas: HTMLCanvasElement;
|
|
38
|
+
private readonly _ctx: CanvasRenderingContext2D;
|
|
39
|
+
private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();
|
|
40
|
+
private get _width(): number {
|
|
41
|
+
return this._optionsService.options.overviewRuler?.width || 0;
|
|
42
|
+
}
|
|
43
|
+
private _animationFrame: number | undefined;
|
|
44
|
+
|
|
45
|
+
private _shouldUpdateDimensions: boolean | undefined = true;
|
|
46
|
+
private _shouldUpdateAnchor: boolean | undefined = true;
|
|
47
|
+
private _lastKnownBufferLength: number = 0;
|
|
48
|
+
|
|
49
|
+
private _containerHeight: number | undefined;
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
private readonly _viewportElement: HTMLElement,
|
|
53
|
+
private readonly _screenElement: HTMLElement,
|
|
54
|
+
@IBufferService private readonly _bufferService: IBufferService,
|
|
55
|
+
@IDecorationService private readonly _decorationService: IDecorationService,
|
|
56
|
+
@IRenderService private readonly _renderService: IRenderService,
|
|
57
|
+
@IOptionsService private readonly _optionsService: IOptionsService,
|
|
58
|
+
@IThemeService private readonly _themeService: IThemeService,
|
|
59
|
+
@ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService
|
|
60
|
+
) {
|
|
61
|
+
super();
|
|
62
|
+
this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');
|
|
63
|
+
this._canvas.classList.add('xterm-decoration-overview-ruler');
|
|
64
|
+
this._refreshCanvasDimensions();
|
|
65
|
+
this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);
|
|
66
|
+
this._register(toDisposable(() => this._canvas?.remove()));
|
|
67
|
+
|
|
68
|
+
const ctx = this._canvas.getContext('2d');
|
|
69
|
+
if (!ctx) {
|
|
70
|
+
throw new Error('Ctx cannot be null');
|
|
71
|
+
} else {
|
|
72
|
+
this._ctx = ctx;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));
|
|
76
|
+
this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));
|
|
77
|
+
|
|
78
|
+
this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));
|
|
79
|
+
this._register(this._bufferService.buffers.onBufferActivate(() => {
|
|
80
|
+
this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';
|
|
81
|
+
}));
|
|
82
|
+
this._register(this._bufferService.onScroll(() => {
|
|
83
|
+
if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {
|
|
84
|
+
this._refreshDrawHeightConstants();
|
|
85
|
+
this._refreshColorZonePadding();
|
|
86
|
+
}
|
|
87
|
+
}));
|
|
88
|
+
|
|
89
|
+
// Container height changed
|
|
90
|
+
this._register(this._renderService.onRender((): void => {
|
|
91
|
+
if (!this._containerHeight || this._containerHeight !== this._screenElement.clientHeight) {
|
|
92
|
+
this._queueRefresh(true);
|
|
93
|
+
this._containerHeight = this._screenElement.clientHeight;
|
|
94
|
+
}
|
|
95
|
+
}));
|
|
96
|
+
|
|
97
|
+
this._register(this._coreBrowserService.onDprChange(() => this._queueRefresh(true)));
|
|
98
|
+
this._register(this._optionsService.onSpecificOptionChange('overviewRuler', () => this._queueRefresh(true)));
|
|
99
|
+
this._register(this._themeService.onChangeColors(() => this._queueRefresh()));
|
|
100
|
+
this._queueRefresh(true);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private _refreshDrawConstants(): void {
|
|
104
|
+
// width
|
|
105
|
+
const outerWidth = Math.floor((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);
|
|
106
|
+
const innerWidth = Math.ceil((this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH) / 3);
|
|
107
|
+
drawWidth.full = this._canvas.width;
|
|
108
|
+
drawWidth.left = outerWidth;
|
|
109
|
+
drawWidth.center = innerWidth;
|
|
110
|
+
drawWidth.right = outerWidth;
|
|
111
|
+
// height
|
|
112
|
+
this._refreshDrawHeightConstants();
|
|
113
|
+
// x
|
|
114
|
+
drawX.full = Constants.OVERVIEW_RULER_BORDER_WIDTH;
|
|
115
|
+
drawX.left = Constants.OVERVIEW_RULER_BORDER_WIDTH;
|
|
116
|
+
drawX.center = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left;
|
|
117
|
+
drawX.right = Constants.OVERVIEW_RULER_BORDER_WIDTH + drawWidth.left + drawWidth.center;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
private _refreshDrawHeightConstants(): void {
|
|
121
|
+
drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);
|
|
122
|
+
// Calculate actual pixels per line
|
|
123
|
+
const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;
|
|
124
|
+
// Clamp actual pixels within a range
|
|
125
|
+
const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);
|
|
126
|
+
drawHeight.left = nonFullHeight;
|
|
127
|
+
drawHeight.center = nonFullHeight;
|
|
128
|
+
drawHeight.right = nonFullHeight;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private _refreshColorZonePadding(): void {
|
|
132
|
+
this._colorZoneStore.setPadding({
|
|
133
|
+
full: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.full),
|
|
134
|
+
left: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.left),
|
|
135
|
+
center: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.center),
|
|
136
|
+
right: Math.floor(this._bufferService.buffers.active.lines.length / (this._canvas.height - 1) * drawHeight.right)
|
|
137
|
+
});
|
|
138
|
+
this._lastKnownBufferLength = this._bufferService.buffers.normal.lines.length;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
private _refreshCanvasDimensions(): void {
|
|
142
|
+
this._canvas.style.width = `${this._width}px`;
|
|
143
|
+
this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);
|
|
144
|
+
this._canvas.style.height = `${this._screenElement.clientHeight}px`;
|
|
145
|
+
this._canvas.height = Math.round(this._screenElement.clientHeight * this._coreBrowserService.dpr);
|
|
146
|
+
this._refreshDrawConstants();
|
|
147
|
+
this._refreshColorZonePadding();
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
private _refreshDecorations(): void {
|
|
151
|
+
if (this._shouldUpdateDimensions) {
|
|
152
|
+
this._refreshCanvasDimensions();
|
|
153
|
+
}
|
|
154
|
+
this._ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
|
|
155
|
+
this._colorZoneStore.clear();
|
|
156
|
+
for (const decoration of this._decorationService.decorations) {
|
|
157
|
+
this._colorZoneStore.addDecoration(decoration);
|
|
158
|
+
}
|
|
159
|
+
this._ctx.lineWidth = 1;
|
|
160
|
+
this._renderRulerOutline();
|
|
161
|
+
const zones = this._colorZoneStore.zones;
|
|
162
|
+
for (const zone of zones) {
|
|
163
|
+
if (zone.position !== 'full') {
|
|
164
|
+
this._renderColorZone(zone);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (const zone of zones) {
|
|
168
|
+
if (zone.position === 'full') {
|
|
169
|
+
this._renderColorZone(zone);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
this._shouldUpdateDimensions = false;
|
|
173
|
+
this._shouldUpdateAnchor = false;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
private _renderRulerOutline(): void {
|
|
177
|
+
this._ctx.fillStyle = this._themeService.colors.overviewRulerBorder.css;
|
|
178
|
+
this._ctx.fillRect(0, 0, Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);
|
|
179
|
+
if (this._optionsService.rawOptions.overviewRuler.showTopBorder) {
|
|
180
|
+
this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, 0, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, Constants.OVERVIEW_RULER_BORDER_WIDTH);
|
|
181
|
+
}
|
|
182
|
+
if (this._optionsService.rawOptions.overviewRuler.showBottomBorder) {
|
|
183
|
+
this._ctx.fillRect(Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.width - Constants.OVERVIEW_RULER_BORDER_WIDTH, this._canvas.height);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private _renderColorZone(zone: IColorZone): void {
|
|
188
|
+
this._ctx.fillStyle = zone.color;
|
|
189
|
+
this._ctx.fillRect(
|
|
190
|
+
/* x */ drawX[zone.position || 'full'],
|
|
191
|
+
/* y */ Math.round(
|
|
192
|
+
(this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line
|
|
193
|
+
(zone.startBufferLine / this._bufferService.buffers.active.lines.length) - drawHeight[zone.position || 'full'] / 2
|
|
194
|
+
),
|
|
195
|
+
/* w */ drawWidth[zone.position || 'full'],
|
|
196
|
+
/* h */ Math.round(
|
|
197
|
+
(this._canvas.height - 1) * // -1 to ensure at least 2px are allowed for decoration on last line
|
|
198
|
+
((zone.endBufferLine - zone.startBufferLine) / this._bufferService.buffers.active.lines.length) + drawHeight[zone.position || 'full']
|
|
199
|
+
)
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
private _queueRefresh(updateCanvasDimensions?: boolean, updateAnchor?: boolean): void {
|
|
204
|
+
this._shouldUpdateDimensions = updateCanvasDimensions || this._shouldUpdateDimensions;
|
|
205
|
+
this._shouldUpdateAnchor = updateAnchor || this._shouldUpdateAnchor;
|
|
206
|
+
if (this._animationFrame !== undefined) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {
|
|
210
|
+
this._refreshDecorations();
|
|
211
|
+
this._animationFrame = undefined;
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2016 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { IRenderService } from 'browser/services/Services';
|
|
7
|
+
import { IBufferService, ICoreService, IOptionsService } from 'common/services/Services';
|
|
8
|
+
import { C0 } from 'common/data/EscapeSequences';
|
|
9
|
+
|
|
10
|
+
interface IPosition {
|
|
11
|
+
start: number;
|
|
12
|
+
end: number;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Encapsulates the logic for handling compositionstart, compositionupdate and compositionend
|
|
17
|
+
* events, displaying the in-progress composition to the UI and forwarding the final composition
|
|
18
|
+
* to the handler.
|
|
19
|
+
*/
|
|
20
|
+
export class CompositionHelper {
|
|
21
|
+
/**
|
|
22
|
+
* Whether input composition is currently happening, eg. via a mobile keyboard, speech input or
|
|
23
|
+
* IME. This variable determines whether the compositionText should be displayed on the UI.
|
|
24
|
+
*/
|
|
25
|
+
private _isComposing: boolean;
|
|
26
|
+
public get isComposing(): boolean { return this._isComposing; }
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* The position within the input textarea's value of the current composition.
|
|
30
|
+
*/
|
|
31
|
+
private _compositionPosition: IPosition;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Whether a composition is in the process of being sent, setting this to false will cancel any
|
|
35
|
+
* in-progress composition.
|
|
36
|
+
*/
|
|
37
|
+
private _isSendingComposition: boolean;
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Data already sent due to keydown event.
|
|
41
|
+
*/
|
|
42
|
+
private _dataAlreadySent: string;
|
|
43
|
+
|
|
44
|
+
constructor(
|
|
45
|
+
private readonly _textarea: HTMLTextAreaElement,
|
|
46
|
+
private readonly _compositionView: HTMLElement,
|
|
47
|
+
@IBufferService private readonly _bufferService: IBufferService,
|
|
48
|
+
@IOptionsService private readonly _optionsService: IOptionsService,
|
|
49
|
+
@ICoreService private readonly _coreService: ICoreService,
|
|
50
|
+
@IRenderService private readonly _renderService: IRenderService
|
|
51
|
+
) {
|
|
52
|
+
this._isComposing = false;
|
|
53
|
+
this._isSendingComposition = false;
|
|
54
|
+
this._compositionPosition = { start: 0, end: 0 };
|
|
55
|
+
this._dataAlreadySent = '';
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Handles the compositionstart event, activating the composition view.
|
|
60
|
+
*/
|
|
61
|
+
public compositionstart(): void {
|
|
62
|
+
this._isComposing = true;
|
|
63
|
+
this._compositionPosition.start = this._textarea.value.length;
|
|
64
|
+
this._compositionView.textContent = '';
|
|
65
|
+
this._dataAlreadySent = '';
|
|
66
|
+
this._compositionView.classList.add('active');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Handles the compositionupdate event, updating the composition view.
|
|
71
|
+
* @param ev The event.
|
|
72
|
+
*/
|
|
73
|
+
public compositionupdate(ev: Pick<CompositionEvent, 'data'>): void {
|
|
74
|
+
this._compositionView.textContent = ev.data;
|
|
75
|
+
this.updateCompositionElements();
|
|
76
|
+
setTimeout(() => {
|
|
77
|
+
this._compositionPosition.end = this._textarea.value.length;
|
|
78
|
+
}, 0);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Handles the compositionend event, hiding the composition view and sending the composition to
|
|
83
|
+
* the handler.
|
|
84
|
+
*/
|
|
85
|
+
public compositionend(): void {
|
|
86
|
+
this._finalizeComposition(true);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Handles the keydown event, routing any necessary events to the CompositionHelper functions.
|
|
91
|
+
* @param ev The keydown event.
|
|
92
|
+
* @returns Whether the Terminal should continue processing the keydown event.
|
|
93
|
+
*/
|
|
94
|
+
public keydown(ev: KeyboardEvent): boolean {
|
|
95
|
+
if (this._isComposing || this._isSendingComposition) {
|
|
96
|
+
if (ev.keyCode === 20 || ev.keyCode === 229) {
|
|
97
|
+
// 20 is CapsLock, 229 is Enter
|
|
98
|
+
// Continue composing if the keyCode is the "composition character"
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {
|
|
102
|
+
// Continue composing if the keyCode is a modifier key
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
// Finish composition immediately. This is mainly here for the case where enter is
|
|
106
|
+
// pressed and the handler needs to be triggered before the command is executed.
|
|
107
|
+
this._finalizeComposition(false);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (ev.keyCode === 229) {
|
|
111
|
+
// If the "composition character" is used but gets to this point it means a non-composition
|
|
112
|
+
// character (eg. numbers and punctuation) was pressed when the IME was active.
|
|
113
|
+
this._handleAnyTextareaChanges();
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Finalizes the composition, resuming regular input actions. This is called when a composition
|
|
122
|
+
* is ending.
|
|
123
|
+
* @param waitForPropagation Whether to wait for events to propagate before sending
|
|
124
|
+
* the input. This should be false if a non-composition keystroke is entered before the
|
|
125
|
+
* compositionend event is triggered, such as enter, so that the composition is sent before
|
|
126
|
+
* the command is executed.
|
|
127
|
+
*/
|
|
128
|
+
private _finalizeComposition(waitForPropagation: boolean): void {
|
|
129
|
+
this._compositionView.classList.remove('active');
|
|
130
|
+
this._isComposing = false;
|
|
131
|
+
|
|
132
|
+
if (!waitForPropagation) {
|
|
133
|
+
// Cancel any delayed composition send requests and send the input immediately.
|
|
134
|
+
this._isSendingComposition = false;
|
|
135
|
+
const input = this._textarea.value.substring(this._compositionPosition.start, this._compositionPosition.end);
|
|
136
|
+
this._coreService.triggerDataEvent(input, true);
|
|
137
|
+
} else {
|
|
138
|
+
// Make a deep copy of the composition position here as a new compositionstart event may
|
|
139
|
+
// fire before the setTimeout executes.
|
|
140
|
+
const currentCompositionPosition = {
|
|
141
|
+
start: this._compositionPosition.start,
|
|
142
|
+
end: this._compositionPosition.end
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// Since composition* events happen before the changes take place in the textarea on most
|
|
146
|
+
// browsers, use a setTimeout with 0ms time to allow the native compositionend event to
|
|
147
|
+
// complete. This ensures the correct character is retrieved.
|
|
148
|
+
// This solution was used because:
|
|
149
|
+
// - The compositionend event's data property is unreliable, at least on Chromium
|
|
150
|
+
// - The last compositionupdate event's data property does not always accurately describe
|
|
151
|
+
// the character, a counter example being Korean where an ending consonsant can move to
|
|
152
|
+
// the following character if the following input is a vowel.
|
|
153
|
+
this._isSendingComposition = true;
|
|
154
|
+
setTimeout(() => {
|
|
155
|
+
// Ensure that the input has not already been sent
|
|
156
|
+
if (this._isSendingComposition) {
|
|
157
|
+
this._isSendingComposition = false;
|
|
158
|
+
let input;
|
|
159
|
+
// Add length of data already sent due to keydown event,
|
|
160
|
+
// otherwise input characters can be duplicated. (Issue #3191)
|
|
161
|
+
currentCompositionPosition.start += this._dataAlreadySent.length;
|
|
162
|
+
if (this._isComposing) {
|
|
163
|
+
// Use the start position of the new composition to get the string
|
|
164
|
+
// if a new composition has started.
|
|
165
|
+
input = this._textarea.value.substring(currentCompositionPosition.start, this._compositionPosition.start);
|
|
166
|
+
} else {
|
|
167
|
+
// Don't use the end position here in order to pick up any characters after the
|
|
168
|
+
// composition has finished, for example when typing a non-composition character
|
|
169
|
+
// (eg. 2) after a composition character.
|
|
170
|
+
input = this._textarea.value.substring(currentCompositionPosition.start);
|
|
171
|
+
}
|
|
172
|
+
if (input.length > 0) {
|
|
173
|
+
this._coreService.triggerDataEvent(input, true);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}, 0);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Apply any changes made to the textarea after the current event chain is allowed to complete.
|
|
182
|
+
* This should be called when not currently composing but a keydown event with the "composition
|
|
183
|
+
* character" (229) is triggered, in order to allow non-composition text to be entered when an
|
|
184
|
+
* IME is active.
|
|
185
|
+
*/
|
|
186
|
+
private _handleAnyTextareaChanges(): void {
|
|
187
|
+
const oldValue = this._textarea.value;
|
|
188
|
+
setTimeout(() => {
|
|
189
|
+
// Ignore if a composition has started since the timeout
|
|
190
|
+
if (!this._isComposing) {
|
|
191
|
+
const newValue = this._textarea.value;
|
|
192
|
+
|
|
193
|
+
const diff = newValue.replace(oldValue, '');
|
|
194
|
+
|
|
195
|
+
this._dataAlreadySent = diff;
|
|
196
|
+
|
|
197
|
+
if (newValue.length > oldValue.length) {
|
|
198
|
+
this._coreService.triggerDataEvent(diff, true);
|
|
199
|
+
} else if (newValue.length < oldValue.length) {
|
|
200
|
+
this._coreService.triggerDataEvent(`${C0.DEL}`, true);
|
|
201
|
+
} else if ((newValue.length === oldValue.length) && (newValue !== oldValue)) {
|
|
202
|
+
this._coreService.triggerDataEvent(newValue, true);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
}
|
|
206
|
+
}, 0);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Positions the composition view on top of the cursor and the textarea just below it (so the
|
|
211
|
+
* IME helper dialog is positioned correctly).
|
|
212
|
+
* @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is
|
|
213
|
+
* necessary as the IME events across browsers are not consistently triggered.
|
|
214
|
+
*/
|
|
215
|
+
public updateCompositionElements(dontRecurse?: boolean): void {
|
|
216
|
+
if (!this._isComposing) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
if (this._bufferService.buffer.isCursorInViewport) {
|
|
221
|
+
const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);
|
|
222
|
+
|
|
223
|
+
const cellHeight = this._renderService.dimensions.css.cell.height;
|
|
224
|
+
const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.css.cell.height;
|
|
225
|
+
const cursorLeft = cursorX * this._renderService.dimensions.css.cell.width;
|
|
226
|
+
|
|
227
|
+
this._compositionView.style.left = cursorLeft + 'px';
|
|
228
|
+
this._compositionView.style.top = cursorTop + 'px';
|
|
229
|
+
this._compositionView.style.height = cellHeight + 'px';
|
|
230
|
+
this._compositionView.style.lineHeight = cellHeight + 'px';
|
|
231
|
+
this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;
|
|
232
|
+
this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';
|
|
233
|
+
// Sync the textarea to the exact position of the composition view so the IME knows where the
|
|
234
|
+
// text is.
|
|
235
|
+
const compositionViewBounds = this._compositionView.getBoundingClientRect();
|
|
236
|
+
this._textarea.style.left = cursorLeft + 'px';
|
|
237
|
+
this._textarea.style.top = cursorTop + 'px';
|
|
238
|
+
// Ensure the text area is at least 1x1, otherwise certain IMEs may break
|
|
239
|
+
this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';
|
|
240
|
+
this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';
|
|
241
|
+
this._textarea.style.lineHeight = compositionViewBounds.height + 'px';
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
if (!dontRecurse) {
|
|
245
|
+
setTimeout(() => this.updateCompositionElements(true), 0);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
|
3
|
+
* @license MIT
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export function getCoordsRelativeToElement(window: Pick<Window, 'getComputedStyle'>, event: {clientX: number, clientY: number}, element: HTMLElement): [number, number] {
|
|
7
|
+
const rect = element.getBoundingClientRect();
|
|
8
|
+
const elementStyle = window.getComputedStyle(element);
|
|
9
|
+
const leftPadding = parseInt(elementStyle.getPropertyValue('padding-left'));
|
|
10
|
+
const topPadding = parseInt(elementStyle.getPropertyValue('padding-top'));
|
|
11
|
+
return [
|
|
12
|
+
event.clientX - rect.left - leftPadding,
|
|
13
|
+
event.clientY - rect.top - topPadding
|
|
14
|
+
];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Gets coordinates within the terminal for a particular mouse event. The result
|
|
19
|
+
* is returned as an array in the form [x, y] instead of an object as it's a
|
|
20
|
+
* little faster and this function is used in some low level code.
|
|
21
|
+
* @param window The window object the element belongs to.
|
|
22
|
+
* @param event The mouse event.
|
|
23
|
+
* @param element The terminal's container element.
|
|
24
|
+
* @param colCount The number of columns in the terminal.
|
|
25
|
+
* @param rowCount The number of rows n the terminal.
|
|
26
|
+
* @param hasValidCharSize Whether there is a valid character size available.
|
|
27
|
+
* @param cssCellWidth The cell width device pixel render dimensions.
|
|
28
|
+
* @param cssCellHeight The cell height device pixel render dimensions.
|
|
29
|
+
* @param isSelection Whether the request is for the selection or not. This will
|
|
30
|
+
* apply an offset to the x value such that the left half of the cell will
|
|
31
|
+
* select that cell and the right half will select the next cell.
|
|
32
|
+
*/
|
|
33
|
+
export function getCoords(window: Pick<Window, 'getComputedStyle'>, event: Pick<MouseEvent, 'clientX' | 'clientY'>, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, cssCellWidth: number, cssCellHeight: number, isSelection?: boolean): [number, number] | undefined {
|
|
34
|
+
// Coordinates cannot be measured if there are no valid
|
|
35
|
+
if (!hasValidCharSize) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const coords = getCoordsRelativeToElement(window, event, element);
|
|
40
|
+
if (!coords) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
coords[0] = Math.ceil((coords[0] + (isSelection ? cssCellWidth / 2 : 0)) / cssCellWidth);
|
|
45
|
+
coords[1] = Math.ceil(coords[1] / cssCellHeight);
|
|
46
|
+
|
|
47
|
+
// Ensure coordinates are within the terminal viewport. Note that selections
|
|
48
|
+
// need an addition point of precision to cover the end point (as characters
|
|
49
|
+
// cover half of one char and half of the next).
|
|
50
|
+
coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));
|
|
51
|
+
coords[1] = Math.min(Math.max(coords[1], 1), rowCount);
|
|
52
|
+
|
|
53
|
+
return coords;
|
|
54
|
+
}
|