@wendongfly/myhi 1.0.2 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/lib/xterm/LICENSE +21 -0
  3. package/dist/lib/xterm/README.md +225 -0
  4. package/dist/lib/xterm/css/xterm.css +190 -0
  5. package/dist/lib/xterm/lib/xterm.js +2 -0
  6. package/dist/lib/xterm/lib/xterm.js.map +1 -0
  7. package/dist/lib/xterm/package.json +90 -0
  8. package/dist/lib/xterm/src/browser/AccessibilityManager.ts +301 -0
  9. package/dist/lib/xterm/src/browser/Clipboard.ts +99 -0
  10. package/dist/lib/xterm/src/browser/ColorContrastCache.ts +39 -0
  11. package/dist/lib/xterm/src/browser/ColorManager.ts +268 -0
  12. package/dist/lib/xterm/src/browser/Dom.ts +10 -0
  13. package/dist/lib/xterm/src/browser/Lifecycle.ts +30 -0
  14. package/dist/lib/xterm/src/browser/Linkifier.ts +356 -0
  15. package/dist/lib/xterm/src/browser/Linkifier2.ts +397 -0
  16. package/dist/lib/xterm/src/browser/LocalizableStrings.ts +10 -0
  17. package/dist/lib/xterm/src/browser/MouseZoneManager.ts +236 -0
  18. package/dist/lib/xterm/src/browser/RenderDebouncer.ts +82 -0
  19. package/dist/lib/xterm/src/browser/ScreenDprMonitor.ts +69 -0
  20. package/dist/lib/xterm/src/browser/Terminal.ts +1447 -0
  21. package/dist/lib/xterm/src/browser/TimeBasedDebouncer.ts +86 -0
  22. package/dist/lib/xterm/src/browser/Types.d.ts +317 -0
  23. package/dist/lib/xterm/src/browser/Viewport.ts +276 -0
  24. package/dist/lib/xterm/src/browser/decorations/BufferDecorationRenderer.ts +131 -0
  25. package/dist/lib/xterm/src/browser/decorations/ColorZoneStore.ts +117 -0
  26. package/dist/lib/xterm/src/browser/decorations/OverviewRulerRenderer.ts +228 -0
  27. package/dist/lib/xterm/src/browser/input/CompositionHelper.ts +237 -0
  28. package/dist/lib/xterm/src/browser/input/Mouse.ts +64 -0
  29. package/dist/lib/xterm/src/browser/input/MoveToCell.ts +249 -0
  30. package/dist/lib/xterm/src/browser/public/Terminal.ts +298 -0
  31. package/dist/lib/xterm/src/browser/renderer/BaseRenderLayer.ts +582 -0
  32. package/dist/lib/xterm/src/browser/renderer/CursorRenderLayer.ts +378 -0
  33. package/dist/lib/xterm/src/browser/renderer/CustomGlyphs.ts +632 -0
  34. package/dist/lib/xterm/src/browser/renderer/GridCache.ts +33 -0
  35. package/dist/lib/xterm/src/browser/renderer/LinkRenderLayer.ts +84 -0
  36. package/dist/lib/xterm/src/browser/renderer/Renderer.ts +219 -0
  37. package/dist/lib/xterm/src/browser/renderer/RendererUtils.ts +26 -0
  38. package/dist/lib/xterm/src/browser/renderer/SelectionRenderLayer.ts +131 -0
  39. package/dist/lib/xterm/src/browser/renderer/TextRenderLayer.ts +344 -0
  40. package/dist/lib/xterm/src/browser/renderer/Types.d.ts +109 -0
  41. package/dist/lib/xterm/src/browser/renderer/atlas/BaseCharAtlas.ts +58 -0
  42. package/dist/lib/xterm/src/browser/renderer/atlas/CharAtlasCache.ts +95 -0
  43. package/dist/lib/xterm/src/browser/renderer/atlas/CharAtlasUtils.ts +54 -0
  44. package/dist/lib/xterm/src/browser/renderer/atlas/Constants.ts +15 -0
  45. package/dist/lib/xterm/src/browser/renderer/atlas/DynamicCharAtlas.ts +404 -0
  46. package/dist/lib/xterm/src/browser/renderer/atlas/LRUMap.ts +136 -0
  47. package/dist/lib/xterm/src/browser/renderer/atlas/Types.d.ts +29 -0
  48. package/dist/lib/xterm/src/browser/renderer/dom/DomRenderer.ts +403 -0
  49. package/dist/lib/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +344 -0
  50. package/dist/lib/xterm/src/browser/selection/SelectionModel.ts +144 -0
  51. package/dist/lib/xterm/src/browser/selection/Types.d.ts +15 -0
  52. package/dist/lib/xterm/src/browser/services/CharSizeService.ts +87 -0
  53. package/dist/lib/xterm/src/browser/services/CharacterJoinerService.ts +339 -0
  54. package/dist/lib/xterm/src/browser/services/CoreBrowserService.ts +20 -0
  55. package/dist/lib/xterm/src/browser/services/MouseService.ts +36 -0
  56. package/dist/lib/xterm/src/browser/services/RenderService.ts +237 -0
  57. package/dist/lib/xterm/src/browser/services/SelectionService.ts +1027 -0
  58. package/dist/lib/xterm/src/browser/services/Services.ts +123 -0
  59. package/dist/lib/xterm/src/browser/services/SoundService.ts +63 -0
  60. package/dist/lib/xterm/src/common/CircularList.ts +239 -0
  61. package/dist/lib/xterm/src/common/Clone.ts +23 -0
  62. package/dist/lib/xterm/src/common/Color.ts +285 -0
  63. package/dist/lib/xterm/src/common/CoreTerminal.ts +300 -0
  64. package/dist/lib/xterm/src/common/EventEmitter.ts +69 -0
  65. package/dist/lib/xterm/src/common/InputHandler.ts +3230 -0
  66. package/dist/lib/xterm/src/common/Lifecycle.ts +68 -0
  67. package/dist/lib/xterm/src/common/Platform.ts +31 -0
  68. package/dist/lib/xterm/src/common/SortedList.ts +88 -0
  69. package/dist/lib/xterm/src/common/TypedArrayUtils.ts +50 -0
  70. package/dist/lib/xterm/src/common/Types.d.ts +489 -0
  71. package/dist/lib/xterm/src/common/WindowsMode.ts +27 -0
  72. package/dist/lib/xterm/src/common/buffer/AttributeData.ts +148 -0
  73. package/dist/lib/xterm/src/common/buffer/Buffer.ts +711 -0
  74. package/dist/lib/xterm/src/common/buffer/BufferLine.ts +441 -0
  75. package/dist/lib/xterm/src/common/buffer/BufferRange.ts +13 -0
  76. package/dist/lib/xterm/src/common/buffer/BufferReflow.ts +220 -0
  77. package/dist/lib/xterm/src/common/buffer/BufferSet.ts +131 -0
  78. package/dist/lib/xterm/src/common/buffer/CellData.ts +94 -0
  79. package/dist/lib/xterm/src/common/buffer/Constants.ts +139 -0
  80. package/dist/lib/xterm/src/common/buffer/Marker.ts +37 -0
  81. package/dist/lib/xterm/src/common/buffer/Types.d.ts +64 -0
  82. package/dist/lib/xterm/src/common/data/Charsets.ts +256 -0
  83. package/dist/lib/xterm/src/common/data/EscapeSequences.ts +153 -0
  84. package/dist/lib/xterm/src/common/input/Keyboard.ts +398 -0
  85. package/dist/lib/xterm/src/common/input/TextDecoder.ts +346 -0
  86. package/dist/lib/xterm/src/common/input/UnicodeV6.ts +133 -0
  87. package/dist/lib/xterm/src/common/input/WriteBuffer.ts +229 -0
  88. package/dist/lib/xterm/src/common/input/XParseColor.ts +80 -0
  89. package/dist/lib/xterm/src/common/parser/Constants.ts +58 -0
  90. package/dist/lib/xterm/src/common/parser/DcsParser.ts +192 -0
  91. package/dist/lib/xterm/src/common/parser/EscapeSequenceParser.ts +796 -0
  92. package/dist/lib/xterm/src/common/parser/OscParser.ts +238 -0
  93. package/dist/lib/xterm/src/common/parser/Params.ts +229 -0
  94. package/dist/lib/xterm/src/common/parser/Types.d.ts +274 -0
  95. package/dist/lib/xterm/src/common/public/AddonManager.ts +56 -0
  96. package/dist/lib/xterm/src/common/public/BufferApiView.ts +35 -0
  97. package/dist/lib/xterm/src/common/public/BufferLineApiView.ts +29 -0
  98. package/dist/lib/xterm/src/common/public/BufferNamespaceApi.ts +33 -0
  99. package/dist/lib/xterm/src/common/public/ParserApi.ts +37 -0
  100. package/dist/lib/xterm/src/common/public/UnicodeApi.ts +27 -0
  101. package/dist/lib/xterm/src/common/services/BufferService.ts +185 -0
  102. package/dist/lib/xterm/src/common/services/CharsetService.ts +34 -0
  103. package/dist/lib/xterm/src/common/services/CoreMouseService.ts +309 -0
  104. package/dist/lib/xterm/src/common/services/CoreService.ts +92 -0
  105. package/dist/lib/xterm/src/common/services/DecorationService.ts +139 -0
  106. package/dist/lib/xterm/src/common/services/DirtyRowService.ts +53 -0
  107. package/dist/lib/xterm/src/common/services/InstantiationService.ts +83 -0
  108. package/dist/lib/xterm/src/common/services/LogService.ts +88 -0
  109. package/dist/lib/xterm/src/common/services/OptionsService.ts +178 -0
  110. package/dist/lib/xterm/src/common/services/ServiceRegistry.ts +49 -0
  111. package/dist/lib/xterm/src/common/services/Services.ts +323 -0
  112. package/dist/lib/xterm/src/common/services/UnicodeService.ts +82 -0
  113. package/dist/lib/xterm/src/headless/Terminal.ts +170 -0
  114. package/dist/lib/xterm/src/headless/Types.d.ts +31 -0
  115. package/dist/lib/xterm/src/headless/public/Terminal.ts +216 -0
  116. package/dist/lib/xterm/typings/xterm.d.ts +1872 -0
  117. package/dist/lib/xterm-fit/LICENSE +19 -0
  118. package/dist/lib/xterm-fit/README.md +24 -0
  119. package/dist/lib/xterm-fit/lib/xterm-addon-fit.js +2 -0
  120. package/dist/lib/xterm-fit/lib/xterm-addon-fit.js.map +1 -0
  121. package/dist/lib/xterm-fit/out/FitAddon.js +58 -0
  122. package/dist/lib/xterm-fit/out/FitAddon.js.map +1 -0
  123. package/dist/lib/xterm-fit/out-test/FitAddon.api.js.map +1 -0
  124. package/dist/lib/xterm-fit/package.json +21 -0
  125. package/dist/lib/xterm-fit/src/FitAddon.ts +86 -0
  126. package/dist/lib/xterm-fit/typings/xterm-addon-fit.d.ts +55 -0
  127. package/dist/lib/xterm-links/LICENSE +19 -0
  128. package/dist/lib/xterm-links/README.md +21 -0
  129. package/dist/lib/xterm-links/lib/xterm-addon-web-links.js +2 -0
  130. package/dist/lib/xterm-links/lib/xterm-addon-web-links.js.map +1 -0
  131. package/dist/lib/xterm-links/package.json +26 -0
  132. package/dist/lib/xterm-links/src/WebLinkProvider.ts +145 -0
  133. package/dist/lib/xterm-links/src/WebLinksAddon.ts +77 -0
  134. package/dist/lib/xterm-links/typings/xterm-addon-web-links.d.ts +58 -0
  135. package/package.json +1 -1
@@ -0,0 +1,237 @@
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
+
9
+ interface IPosition {
10
+ start: number;
11
+ end: number;
12
+ }
13
+
14
+ /**
15
+ * Encapsulates the logic for handling compositionstart, compositionupdate and compositionend
16
+ * events, displaying the in-progress composition to the UI and forwarding the final composition
17
+ * to the handler.
18
+ */
19
+ export class CompositionHelper {
20
+ /**
21
+ * Whether input composition is currently happening, eg. via a mobile keyboard, speech input or
22
+ * IME. This variable determines whether the compositionText should be displayed on the UI.
23
+ */
24
+ private _isComposing: boolean;
25
+ public get isComposing(): boolean { return this._isComposing; }
26
+
27
+ /**
28
+ * The position within the input textarea's value of the current composition.
29
+ */
30
+ private _compositionPosition: IPosition;
31
+
32
+ /**
33
+ * Whether a composition is in the process of being sent, setting this to false will cancel any
34
+ * in-progress composition.
35
+ */
36
+ private _isSendingComposition: boolean;
37
+
38
+ /**
39
+ * Data already sent due to keydown event.
40
+ */
41
+ private _dataAlreadySent: string;
42
+
43
+ constructor(
44
+ private readonly _textarea: HTMLTextAreaElement,
45
+ private readonly _compositionView: HTMLElement,
46
+ @IBufferService private readonly _bufferService: IBufferService,
47
+ @IOptionsService private readonly _optionsService: IOptionsService,
48
+ @ICoreService private readonly _coreService: ICoreService,
49
+ @IRenderService private readonly _renderService: IRenderService
50
+ ) {
51
+ this._isComposing = false;
52
+ this._isSendingComposition = false;
53
+ this._compositionPosition = { start: 0, end: 0 };
54
+ this._dataAlreadySent = '';
55
+ }
56
+
57
+ /**
58
+ * Handles the compositionstart event, activating the composition view.
59
+ */
60
+ public compositionstart(): void {
61
+ this._isComposing = true;
62
+ this._compositionPosition.start = this._textarea.value.length;
63
+ this._compositionView.textContent = '';
64
+ this._dataAlreadySent = '';
65
+ this._compositionView.classList.add('active');
66
+ }
67
+
68
+ /**
69
+ * Handles the compositionupdate event, updating the composition view.
70
+ * @param ev The event.
71
+ */
72
+ public compositionupdate(ev: Pick<CompositionEvent, 'data'>): void {
73
+ this._compositionView.textContent = ev.data;
74
+ this.updateCompositionElements();
75
+ setTimeout(() => {
76
+ this._compositionPosition.end = this._textarea.value.length;
77
+ }, 0);
78
+ }
79
+
80
+ /**
81
+ * Handles the compositionend event, hiding the composition view and sending the composition to
82
+ * the handler.
83
+ */
84
+ public compositionend(): void {
85
+ this._finalizeComposition(true);
86
+ }
87
+
88
+ /**
89
+ * Handles the keydown event, routing any necessary events to the CompositionHelper functions.
90
+ * @param ev The keydown event.
91
+ * @return Whether the Terminal should continue processing the keydown event.
92
+ */
93
+ public keydown(ev: KeyboardEvent): boolean {
94
+ if (this._isComposing || this._isSendingComposition) {
95
+ if (ev.keyCode === 229) {
96
+ // Continue composing if the keyCode is the "composition character"
97
+ return false;
98
+ }
99
+ if (ev.keyCode === 16 || ev.keyCode === 17 || ev.keyCode === 18) {
100
+ // Continue composing if the keyCode is a modifier key
101
+ return false;
102
+ }
103
+ // Finish composition immediately. This is mainly here for the case where enter is
104
+ // pressed and the handler needs to be triggered before the command is executed.
105
+ this._finalizeComposition(false);
106
+ }
107
+
108
+ if (ev.keyCode === 229) {
109
+ // If the "composition character" is used but gets to this point it means a non-composition
110
+ // character (eg. numbers and punctuation) was pressed when the IME was active.
111
+ this._handleAnyTextareaChanges();
112
+ return false;
113
+ }
114
+
115
+ return true;
116
+ }
117
+
118
+ /**
119
+ * Finalizes the composition, resuming regular input actions. This is called when a composition
120
+ * is ending.
121
+ * @param waitForPropagation Whether to wait for events to propagate before sending
122
+ * the input. This should be false if a non-composition keystroke is entered before the
123
+ * compositionend event is triggered, such as enter, so that the composition is sent before
124
+ * the command is executed.
125
+ */
126
+ private _finalizeComposition(waitForPropagation: boolean): void {
127
+ this._compositionView.classList.remove('active');
128
+ this._isComposing = false;
129
+
130
+ if (!waitForPropagation) {
131
+ // Cancel any delayed composition send requests and send the input immediately.
132
+ this._isSendingComposition = false;
133
+ const input = this._textarea.value.substring(this._compositionPosition.start, this._compositionPosition.end);
134
+ this._coreService.triggerDataEvent(input, true);
135
+ } else {
136
+ // Make a deep copy of the composition position here as a new compositionstart event may
137
+ // fire before the setTimeout executes.
138
+ const currentCompositionPosition = {
139
+ start: this._compositionPosition.start,
140
+ end: this._compositionPosition.end
141
+ };
142
+
143
+ // Since composition* events happen before the changes take place in the textarea on most
144
+ // browsers, use a setTimeout with 0ms time to allow the native compositionend event to
145
+ // complete. This ensures the correct character is retrieved.
146
+ // This solution was used because:
147
+ // - The compositionend event's data property is unreliable, at least on Chromium
148
+ // - The last compositionupdate event's data property does not always accurately describe
149
+ // the character, a counter example being Korean where an ending consonsant can move to
150
+ // the following character if the following input is a vowel.
151
+ this._isSendingComposition = true;
152
+ setTimeout(() => {
153
+ // Ensure that the input has not already been sent
154
+ if (this._isSendingComposition) {
155
+ this._isSendingComposition = false;
156
+ let input;
157
+ // Add length of data already sent due to keydown event,
158
+ // otherwise input characters can be duplicated. (Issue #3191)
159
+ currentCompositionPosition.start += this._dataAlreadySent.length;
160
+ if (this._isComposing) {
161
+ // Use the end position to get the string if a new composition has started.
162
+ input = this._textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);
163
+ } else {
164
+ // Don't use the end position here in order to pick up any characters after the
165
+ // composition has finished, for example when typing a non-composition character
166
+ // (eg. 2) after a composition character.
167
+ input = this._textarea.value.substring(currentCompositionPosition.start);
168
+ }
169
+ if (input.length > 0) {
170
+ this._coreService.triggerDataEvent(input, true);
171
+ }
172
+ }
173
+ }, 0);
174
+ }
175
+ }
176
+
177
+ /**
178
+ * Apply any changes made to the textarea after the current event chain is allowed to complete.
179
+ * This should be called when not currently composing but a keydown event with the "composition
180
+ * character" (229) is triggered, in order to allow non-composition text to be entered when an
181
+ * IME is active.
182
+ */
183
+ private _handleAnyTextareaChanges(): void {
184
+ const oldValue = this._textarea.value;
185
+ setTimeout(() => {
186
+ // Ignore if a composition has started since the timeout
187
+ if (!this._isComposing) {
188
+ const newValue = this._textarea.value;
189
+ const diff = newValue.replace(oldValue, '');
190
+ if (diff.length > 0) {
191
+ this._dataAlreadySent = diff;
192
+ this._coreService.triggerDataEvent(diff, true);
193
+ }
194
+ }
195
+ }, 0);
196
+ }
197
+
198
+ /**
199
+ * Positions the composition view on top of the cursor and the textarea just below it (so the
200
+ * IME helper dialog is positioned correctly).
201
+ * @param dontRecurse Whether to use setTimeout to recursively trigger another update, this is
202
+ * necessary as the IME events across browsers are not consistently triggered.
203
+ */
204
+ public updateCompositionElements(dontRecurse?: boolean): void {
205
+ if (!this._isComposing) {
206
+ return;
207
+ }
208
+
209
+ if (this._bufferService.buffer.isCursorInViewport) {
210
+ const cursorX = Math.min(this._bufferService.buffer.x, this._bufferService.cols - 1);
211
+
212
+ const cellHeight = this._renderService.dimensions.actualCellHeight;
213
+ const cursorTop = this._bufferService.buffer.y * this._renderService.dimensions.actualCellHeight;
214
+ const cursorLeft = cursorX * this._renderService.dimensions.actualCellWidth;
215
+
216
+ this._compositionView.style.left = cursorLeft + 'px';
217
+ this._compositionView.style.top = cursorTop + 'px';
218
+ this._compositionView.style.height = cellHeight + 'px';
219
+ this._compositionView.style.lineHeight = cellHeight + 'px';
220
+ this._compositionView.style.fontFamily = this._optionsService.rawOptions.fontFamily;
221
+ this._compositionView.style.fontSize = this._optionsService.rawOptions.fontSize + 'px';
222
+ // Sync the textarea to the exact position of the composition view so the IME knows where the
223
+ // text is.
224
+ const compositionViewBounds = this._compositionView.getBoundingClientRect();
225
+ this._textarea.style.left = cursorLeft + 'px';
226
+ this._textarea.style.top = cursorTop + 'px';
227
+ // Ensure the text area is at least 1x1, otherwise certain IMEs may break
228
+ this._textarea.style.width = Math.max(compositionViewBounds.width, 1) + 'px';
229
+ this._textarea.style.height = Math.max(compositionViewBounds.height, 1) + 'px';
230
+ this._textarea.style.lineHeight = compositionViewBounds.height + 'px';
231
+ }
232
+
233
+ if (!dontRecurse) {
234
+ setTimeout(() => this.updateCompositionElements(true), 0);
235
+ }
236
+ }
237
+ }
@@ -0,0 +1,64 @@
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 event The mouse event.
22
+ * @param element The terminal's container element.
23
+ * @param colCount The number of columns in the terminal.
24
+ * @param rowCount The number of rows n the terminal.
25
+ * @param isSelection Whether the request is for the selection or not. This will
26
+ * apply an offset to the x value such that the left half of the cell will
27
+ * select that cell and the right half will select the next cell.
28
+ */
29
+ export function getCoords(window: Pick<Window, 'getComputedStyle'>, event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, hasValidCharSize: boolean, actualCellWidth: number, actualCellHeight: number, isSelection?: boolean): [number, number] | undefined {
30
+ // Coordinates cannot be measured if there are no valid
31
+ if (!hasValidCharSize) {
32
+ return undefined;
33
+ }
34
+
35
+ const coords = getCoordsRelativeToElement(window, event, element);
36
+ if (!coords) {
37
+ return undefined;
38
+ }
39
+
40
+ coords[0] = Math.ceil((coords[0] + (isSelection ? actualCellWidth / 2 : 0)) / actualCellWidth);
41
+ coords[1] = Math.ceil(coords[1] / actualCellHeight);
42
+
43
+ // Ensure coordinates are within the terminal viewport. Note that selections
44
+ // need an addition point of precision to cover the end point (as characters
45
+ // cover half of one char and half of the next).
46
+ coords[0] = Math.min(Math.max(coords[0], 1), colCount + (isSelection ? 1 : 0));
47
+ coords[1] = Math.min(Math.max(coords[1], 1), rowCount);
48
+
49
+ return coords;
50
+ }
51
+
52
+ /**
53
+ * Gets coordinates within the terminal for a particular mouse event, wrapping
54
+ * them to the bounds of the terminal and adding 32 to both the x and y values
55
+ * as expected by xterm.
56
+ */
57
+ export function getRawByteCoords(coords: [number, number] | undefined): { x: number, y: number } | undefined {
58
+ if (!coords) {
59
+ return undefined;
60
+ }
61
+
62
+ // xterm sends raw bytes and starts at 32 (SP) for each.
63
+ return { x: coords[0] + 32, y: coords[1] + 32 };
64
+ }
@@ -0,0 +1,249 @@
1
+ /**
2
+ * Copyright (c) 2018 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { C0 } from 'common/data/EscapeSequences';
7
+ import { IBufferService } from 'common/services/Services';
8
+
9
+ const enum Direction {
10
+ UP = 'A',
11
+ DOWN = 'B',
12
+ RIGHT = 'C',
13
+ LEFT = 'D'
14
+ }
15
+
16
+ /**
17
+ * Concatenates all the arrow sequences together.
18
+ * Resets the starting row to an unwrapped row, moves to the requested row,
19
+ * then moves to requested col.
20
+ */
21
+ export function moveToCellSequence(targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
22
+ const startX = bufferService.buffer.x;
23
+ const startY = bufferService.buffer.y;
24
+
25
+ // The alt buffer should try to navigate between rows
26
+ if (!bufferService.buffer.hasScrollback) {
27
+ return resetStartingRow(startX, startY, targetX, targetY, bufferService, applicationCursor) +
28
+ moveToRequestedRow(startY, targetY, bufferService, applicationCursor) +
29
+ moveToRequestedCol(startX, startY, targetX, targetY, bufferService, applicationCursor);
30
+ }
31
+
32
+ // Only move horizontally for the normal buffer
33
+ let direction;
34
+ if (startY === targetY) {
35
+ direction = startX > targetX ? Direction.LEFT : Direction.RIGHT;
36
+ return repeat(Math.abs(startX - targetX), sequence(direction, applicationCursor));
37
+ }
38
+ direction = startY > targetY ? Direction.LEFT : Direction.RIGHT;
39
+ const rowDifference = Math.abs(startY - targetY);
40
+ const cellsToMove = colsFromRowEnd(startY > targetY ? targetX : startX, bufferService) +
41
+ (rowDifference - 1) * bufferService.cols + 1 /* wrap around 1 row */ +
42
+ colsFromRowBeginning(startY > targetY ? startX : targetX, bufferService);
43
+ return repeat(cellsToMove, sequence(direction, applicationCursor));
44
+ }
45
+
46
+ /**
47
+ * Find the number of cols from a row beginning to a col.
48
+ */
49
+ function colsFromRowBeginning(currX: number, bufferService: IBufferService): number {
50
+ return currX - 1;
51
+ }
52
+
53
+ /**
54
+ * Find the number of cols from a col to row end.
55
+ */
56
+ function colsFromRowEnd(currX: number, bufferService: IBufferService): number {
57
+ return bufferService.cols - currX;
58
+ }
59
+
60
+ /**
61
+ * If the initial position of the cursor is on a row that is wrapped, move the
62
+ * cursor up to the first row that is not wrapped to have accurate vertical
63
+ * positioning.
64
+ */
65
+ function resetStartingRow(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
66
+ if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length === 0) {
67
+ return '';
68
+ }
69
+ return repeat(bufferLine(
70
+ startX, startY, startX,
71
+ startY - wrappedRowsForRow(bufferService, startY), false, bufferService
72
+ ).length, sequence(Direction.LEFT, applicationCursor));
73
+ }
74
+
75
+ /**
76
+ * Using the reset starting and ending row, move to the requested row,
77
+ * ignoring wrapped rows
78
+ */
79
+ function moveToRequestedRow(startY: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
80
+ const startRow = startY - wrappedRowsForRow(bufferService, startY);
81
+ const endRow = targetY - wrappedRowsForRow(bufferService, targetY);
82
+
83
+ const rowsToMove = Math.abs(startRow - endRow) - wrappedRowsCount(startY, targetY, bufferService);
84
+
85
+ return repeat(rowsToMove, sequence(verticalDirection(startY, targetY), applicationCursor));
86
+ }
87
+
88
+ /**
89
+ * Move to the requested col on the ending row
90
+ */
91
+ function moveToRequestedCol(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): string {
92
+ let startRow;
93
+ if (moveToRequestedRow(startY, targetY, bufferService, applicationCursor).length > 0) {
94
+ startRow = targetY - wrappedRowsForRow(bufferService, targetY);
95
+ } else {
96
+ startRow = startY;
97
+ }
98
+
99
+ const endRow = targetY;
100
+ const direction = horizontalDirection(startX, startY, targetX, targetY, bufferService, applicationCursor);
101
+
102
+ return repeat(bufferLine(
103
+ startX, startRow, targetX, endRow,
104
+ direction === Direction.RIGHT, bufferService
105
+ ).length, sequence(direction, applicationCursor));
106
+ }
107
+
108
+ /**
109
+ * Utility functions
110
+ */
111
+
112
+ /**
113
+ * Calculates the number of wrapped rows between the unwrapped starting and
114
+ * ending rows. These rows need to ignored since the cursor skips over them.
115
+ */
116
+ function wrappedRowsCount(startY: number, targetY: number, bufferService: IBufferService): number {
117
+ let wrappedRows = 0;
118
+ const startRow = startY - wrappedRowsForRow(bufferService, startY);
119
+ const endRow = targetY - wrappedRowsForRow(bufferService, targetY);
120
+
121
+ for (let i = 0; i < Math.abs(startRow - endRow); i++) {
122
+ const direction = verticalDirection(startY, targetY) === Direction.UP ? -1 : 1;
123
+ const line = bufferService.buffer.lines.get(startRow + (direction * i));
124
+ if (line?.isWrapped) {
125
+ wrappedRows++;
126
+ }
127
+ }
128
+
129
+ return wrappedRows;
130
+ }
131
+
132
+ /**
133
+ * Calculates the number of wrapped rows that make up a given row.
134
+ * @param currentRow The row to determine how many wrapped rows make it up
135
+ */
136
+ function wrappedRowsForRow(bufferService: IBufferService, currentRow: number): number {
137
+ let rowCount = 0;
138
+ let line = bufferService.buffer.lines.get(currentRow);
139
+ let lineWraps = line?.isWrapped;
140
+
141
+ while (lineWraps && currentRow >= 0 && currentRow < bufferService.rows) {
142
+ rowCount++;
143
+ line = bufferService.buffer.lines.get(--currentRow);
144
+ lineWraps = line?.isWrapped;
145
+ }
146
+
147
+ return rowCount;
148
+ }
149
+
150
+ /**
151
+ * Direction determiners
152
+ */
153
+
154
+ /**
155
+ * Determines if the right or left arrow is needed
156
+ */
157
+ function horizontalDirection(startX: number, startY: number, targetX: number, targetY: number, bufferService: IBufferService, applicationCursor: boolean): Direction {
158
+ let startRow;
159
+ if (moveToRequestedRow(targetX, targetY, bufferService, applicationCursor).length > 0) {
160
+ startRow = targetY - wrappedRowsForRow(bufferService, targetY);
161
+ } else {
162
+ startRow = startY;
163
+ }
164
+
165
+ if ((startX < targetX &&
166
+ startRow <= targetY) || // down/right or same y/right
167
+ (startX >= targetX &&
168
+ startRow < targetY)) { // down/left or same y/left
169
+ return Direction.RIGHT;
170
+ }
171
+ return Direction.LEFT;
172
+ }
173
+
174
+ /**
175
+ * Determines if the up or down arrow is needed
176
+ */
177
+ function verticalDirection(startY: number, targetY: number): Direction {
178
+ return startY > targetY ? Direction.UP : Direction.DOWN;
179
+ }
180
+
181
+ /**
182
+ * Constructs the string of chars in the buffer from a starting row and col
183
+ * to an ending row and col
184
+ * @param startCol The starting column position
185
+ * @param startRow The starting row position
186
+ * @param endCol The ending column position
187
+ * @param endRow The ending row position
188
+ * @param forward Direction to move
189
+ */
190
+ function bufferLine(
191
+ startCol: number,
192
+ startRow: number,
193
+ endCol: number,
194
+ endRow: number,
195
+ forward: boolean,
196
+ bufferService: IBufferService
197
+ ): string {
198
+ let currentCol = startCol;
199
+ let currentRow = startRow;
200
+ let bufferStr = '';
201
+
202
+ while (currentCol !== endCol || currentRow !== endRow) {
203
+ currentCol += forward ? 1 : -1;
204
+
205
+ if (forward && currentCol > bufferService.cols - 1) {
206
+ bufferStr += bufferService.buffer.translateBufferLineToString(
207
+ currentRow, false, startCol, currentCol
208
+ );
209
+ currentCol = 0;
210
+ startCol = 0;
211
+ currentRow++;
212
+ } else if (!forward && currentCol < 0) {
213
+ bufferStr += bufferService.buffer.translateBufferLineToString(
214
+ currentRow, false, 0, startCol + 1
215
+ );
216
+ currentCol = bufferService.cols - 1;
217
+ startCol = currentCol;
218
+ currentRow--;
219
+ }
220
+ }
221
+
222
+ return bufferStr + bufferService.buffer.translateBufferLineToString(
223
+ currentRow, false, startCol, currentCol
224
+ );
225
+ }
226
+
227
+ /**
228
+ * Constructs the escape sequence for clicking an arrow
229
+ * @param direction The direction to move
230
+ */
231
+ function sequence(direction: Direction, applicationCursor: boolean): string {
232
+ const mod = applicationCursor ? 'O' : '[';
233
+ return C0.ESC + mod + direction;
234
+ }
235
+
236
+ /**
237
+ * Returns a string repeated a given number of times
238
+ * Polyfill from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
239
+ * @param count The number of times to repeat the string
240
+ * @param string The string that is to be repeated
241
+ */
242
+ function repeat(count: number, str: string): string {
243
+ count = Math.floor(count);
244
+ let rpt = '';
245
+ for (let i = 0; i < count; i++) {
246
+ rpt += str;
247
+ }
248
+ return rpt;
249
+ }