@xterm/xterm 5.4.0-beta.1

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 (108) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +235 -0
  3. package/css/xterm.css +209 -0
  4. package/lib/xterm.js +2 -0
  5. package/lib/xterm.js.map +1 -0
  6. package/package.json +101 -0
  7. package/src/browser/AccessibilityManager.ts +278 -0
  8. package/src/browser/Clipboard.ts +93 -0
  9. package/src/browser/ColorContrastCache.ts +34 -0
  10. package/src/browser/Lifecycle.ts +33 -0
  11. package/src/browser/Linkifier2.ts +416 -0
  12. package/src/browser/LocalizableStrings.ts +12 -0
  13. package/src/browser/OscLinkProvider.ts +128 -0
  14. package/src/browser/RenderDebouncer.ts +83 -0
  15. package/src/browser/Terminal.ts +1317 -0
  16. package/src/browser/TimeBasedDebouncer.ts +86 -0
  17. package/src/browser/Types.d.ts +181 -0
  18. package/src/browser/Viewport.ts +401 -0
  19. package/src/browser/decorations/BufferDecorationRenderer.ts +134 -0
  20. package/src/browser/decorations/ColorZoneStore.ts +117 -0
  21. package/src/browser/decorations/OverviewRulerRenderer.ts +218 -0
  22. package/src/browser/input/CompositionHelper.ts +246 -0
  23. package/src/browser/input/Mouse.ts +54 -0
  24. package/src/browser/input/MoveToCell.ts +249 -0
  25. package/src/browser/public/Terminal.ts +260 -0
  26. package/src/browser/renderer/dom/DomRenderer.ts +509 -0
  27. package/src/browser/renderer/dom/DomRendererRowFactory.ts +526 -0
  28. package/src/browser/renderer/dom/WidthCache.ts +160 -0
  29. package/src/browser/renderer/shared/CellColorResolver.ts +137 -0
  30. package/src/browser/renderer/shared/CharAtlasCache.ts +96 -0
  31. package/src/browser/renderer/shared/CharAtlasUtils.ts +75 -0
  32. package/src/browser/renderer/shared/Constants.ts +14 -0
  33. package/src/browser/renderer/shared/CursorBlinkStateManager.ts +146 -0
  34. package/src/browser/renderer/shared/CustomGlyphs.ts +687 -0
  35. package/src/browser/renderer/shared/DevicePixelObserver.ts +41 -0
  36. package/src/browser/renderer/shared/README.md +1 -0
  37. package/src/browser/renderer/shared/RendererUtils.ts +58 -0
  38. package/src/browser/renderer/shared/SelectionRenderModel.ts +91 -0
  39. package/src/browser/renderer/shared/TextureAtlas.ts +1082 -0
  40. package/src/browser/renderer/shared/Types.d.ts +173 -0
  41. package/src/browser/selection/SelectionModel.ts +144 -0
  42. package/src/browser/selection/Types.d.ts +15 -0
  43. package/src/browser/services/CharSizeService.ts +102 -0
  44. package/src/browser/services/CharacterJoinerService.ts +339 -0
  45. package/src/browser/services/CoreBrowserService.ts +137 -0
  46. package/src/browser/services/MouseService.ts +46 -0
  47. package/src/browser/services/RenderService.ts +279 -0
  48. package/src/browser/services/SelectionService.ts +1031 -0
  49. package/src/browser/services/Services.ts +147 -0
  50. package/src/browser/services/ThemeService.ts +237 -0
  51. package/src/common/CircularList.ts +241 -0
  52. package/src/common/Clone.ts +23 -0
  53. package/src/common/Color.ts +357 -0
  54. package/src/common/CoreTerminal.ts +284 -0
  55. package/src/common/EventEmitter.ts +78 -0
  56. package/src/common/InputHandler.ts +3461 -0
  57. package/src/common/Lifecycle.ts +108 -0
  58. package/src/common/MultiKeyMap.ts +42 -0
  59. package/src/common/Platform.ts +44 -0
  60. package/src/common/SortedList.ts +118 -0
  61. package/src/common/TaskQueue.ts +166 -0
  62. package/src/common/TypedArrayUtils.ts +17 -0
  63. package/src/common/Types.d.ts +553 -0
  64. package/src/common/WindowsMode.ts +27 -0
  65. package/src/common/buffer/AttributeData.ts +196 -0
  66. package/src/common/buffer/Buffer.ts +654 -0
  67. package/src/common/buffer/BufferLine.ts +524 -0
  68. package/src/common/buffer/BufferRange.ts +13 -0
  69. package/src/common/buffer/BufferReflow.ts +223 -0
  70. package/src/common/buffer/BufferSet.ts +134 -0
  71. package/src/common/buffer/CellData.ts +94 -0
  72. package/src/common/buffer/Constants.ts +149 -0
  73. package/src/common/buffer/Marker.ts +43 -0
  74. package/src/common/buffer/Types.d.ts +52 -0
  75. package/src/common/data/Charsets.ts +256 -0
  76. package/src/common/data/EscapeSequences.ts +153 -0
  77. package/src/common/input/Keyboard.ts +398 -0
  78. package/src/common/input/TextDecoder.ts +346 -0
  79. package/src/common/input/UnicodeV6.ts +145 -0
  80. package/src/common/input/WriteBuffer.ts +246 -0
  81. package/src/common/input/XParseColor.ts +80 -0
  82. package/src/common/parser/Constants.ts +58 -0
  83. package/src/common/parser/DcsParser.ts +192 -0
  84. package/src/common/parser/EscapeSequenceParser.ts +792 -0
  85. package/src/common/parser/OscParser.ts +238 -0
  86. package/src/common/parser/Params.ts +229 -0
  87. package/src/common/parser/Types.d.ts +275 -0
  88. package/src/common/public/AddonManager.ts +53 -0
  89. package/src/common/public/BufferApiView.ts +35 -0
  90. package/src/common/public/BufferLineApiView.ts +29 -0
  91. package/src/common/public/BufferNamespaceApi.ts +36 -0
  92. package/src/common/public/ParserApi.ts +37 -0
  93. package/src/common/public/UnicodeApi.ts +27 -0
  94. package/src/common/services/BufferService.ts +151 -0
  95. package/src/common/services/CharsetService.ts +34 -0
  96. package/src/common/services/CoreMouseService.ts +318 -0
  97. package/src/common/services/CoreService.ts +87 -0
  98. package/src/common/services/DecorationService.ts +140 -0
  99. package/src/common/services/InstantiationService.ts +85 -0
  100. package/src/common/services/LogService.ts +124 -0
  101. package/src/common/services/OptionsService.ts +202 -0
  102. package/src/common/services/OscLinkService.ts +115 -0
  103. package/src/common/services/ServiceRegistry.ts +49 -0
  104. package/src/common/services/Services.ts +373 -0
  105. package/src/common/services/UnicodeService.ts +111 -0
  106. package/src/headless/Terminal.ts +136 -0
  107. package/src/headless/public/Terminal.ts +195 -0
  108. package/typings/xterm.d.ts +1857 -0
@@ -0,0 +1,279 @@
1
+ /**
2
+ * Copyright (c) 2019 The xterm.js authors. All rights reserved.
3
+ * @license MIT
4
+ */
5
+
6
+ import { RenderDebouncer } from 'browser/RenderDebouncer';
7
+ import { IRenderDebouncerWithCallback } from 'browser/Types';
8
+ import { IRenderDimensions, IRenderer } from 'browser/renderer/shared/Types';
9
+ import { ICharSizeService, ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
10
+ import { EventEmitter } from 'common/EventEmitter';
11
+ import { Disposable, MutableDisposable } from 'common/Lifecycle';
12
+ import { DebouncedIdleTask } from 'common/TaskQueue';
13
+ import { IBufferService, IDecorationService, IInstantiationService, IOptionsService } from 'common/services/Services';
14
+
15
+ interface ISelectionState {
16
+ start: [number, number] | undefined;
17
+ end: [number, number] | undefined;
18
+ columnSelectMode: boolean;
19
+ }
20
+
21
+ export class RenderService extends Disposable implements IRenderService {
22
+ public serviceBrand: undefined;
23
+
24
+ private _renderer: MutableDisposable<IRenderer> = this.register(new MutableDisposable());
25
+ private _renderDebouncer: IRenderDebouncerWithCallback;
26
+ private _pausedResizeTask = new DebouncedIdleTask();
27
+
28
+ private _isPaused: boolean = false;
29
+ private _needsFullRefresh: boolean = false;
30
+ private _isNextRenderRedrawOnly: boolean = true;
31
+ private _needsSelectionRefresh: boolean = false;
32
+ private _canvasWidth: number = 0;
33
+ private _canvasHeight: number = 0;
34
+ private _selectionState: ISelectionState = {
35
+ start: undefined,
36
+ end: undefined,
37
+ columnSelectMode: false
38
+ };
39
+
40
+ private readonly _onDimensionsChange = this.register(new EventEmitter<IRenderDimensions>());
41
+ public readonly onDimensionsChange = this._onDimensionsChange.event;
42
+ private readonly _onRenderedViewportChange = this.register(new EventEmitter<{ start: number, end: number }>());
43
+ public readonly onRenderedViewportChange = this._onRenderedViewportChange.event;
44
+ private readonly _onRender = this.register(new EventEmitter<{ start: number, end: number }>());
45
+ public readonly onRender = this._onRender.event;
46
+ private readonly _onRefreshRequest = this.register(new EventEmitter<{ start: number, end: number }>());
47
+ public readonly onRefreshRequest = this._onRefreshRequest.event;
48
+
49
+ public get dimensions(): IRenderDimensions { return this._renderer.value!.dimensions; }
50
+
51
+ constructor(
52
+ private _rowCount: number,
53
+ screenElement: HTMLElement,
54
+ @IOptionsService optionsService: IOptionsService,
55
+ @ICharSizeService private readonly _charSizeService: ICharSizeService,
56
+ @IDecorationService decorationService: IDecorationService,
57
+ @IBufferService bufferService: IBufferService,
58
+ @ICoreBrowserService coreBrowserService: ICoreBrowserService,
59
+ @IInstantiationService instantiationService: IInstantiationService,
60
+ @IThemeService themeService: IThemeService
61
+ ) {
62
+ super();
63
+
64
+ this._renderDebouncer = new RenderDebouncer(coreBrowserService.window, (start, end) => this._renderRows(start, end));
65
+ this.register(this._renderDebouncer);
66
+
67
+ this.register(coreBrowserService.onDprChange(() => this.handleDevicePixelRatioChange()));
68
+
69
+ this.register(bufferService.onResize(() => this._fullRefresh()));
70
+ this.register(bufferService.buffers.onBufferActivate(() => this._renderer.value?.clear()));
71
+ this.register(optionsService.onOptionChange(() => this._handleOptionsChanged()));
72
+ this.register(this._charSizeService.onCharSizeChange(() => this.handleCharSizeChanged()));
73
+
74
+ // Do a full refresh whenever any decoration is added or removed. This may not actually result
75
+ // in changes but since decorations should be used sparingly or added/removed all in the same
76
+ // frame this should have minimal performance impact.
77
+ this.register(decorationService.onDecorationRegistered(() => this._fullRefresh()));
78
+ this.register(decorationService.onDecorationRemoved(() => this._fullRefresh()));
79
+
80
+ // Clear the renderer when the a change that could affect glyphs occurs
81
+ this.register(optionsService.onMultipleOptionChange([
82
+ 'customGlyphs',
83
+ 'drawBoldTextInBrightColors',
84
+ 'letterSpacing',
85
+ 'lineHeight',
86
+ 'fontFamily',
87
+ 'fontSize',
88
+ 'fontWeight',
89
+ 'fontWeightBold',
90
+ 'minimumContrastRatio'
91
+ ], () => {
92
+ this.clear();
93
+ this.handleResize(bufferService.cols, bufferService.rows);
94
+ this._fullRefresh();
95
+ }));
96
+
97
+ // Refresh the cursor line when the cursor changes
98
+ this.register(optionsService.onMultipleOptionChange([
99
+ 'cursorBlink',
100
+ 'cursorStyle'
101
+ ], () => this.refreshRows(bufferService.buffer.y, bufferService.buffer.y, true)));
102
+
103
+ this.register(themeService.onChangeColors(() => this._fullRefresh()));
104
+
105
+ // Detect whether IntersectionObserver is detected and enable renderer pause
106
+ // and resume based on terminal visibility if so
107
+ if ('IntersectionObserver' in coreBrowserService.window) {
108
+ const observer = new coreBrowserService.window.IntersectionObserver(e => this._handleIntersectionChange(e[e.length - 1]), { threshold: 0 });
109
+ observer.observe(screenElement);
110
+ this.register({ dispose: () => observer.disconnect() });
111
+ }
112
+ }
113
+
114
+ private _handleIntersectionChange(entry: IntersectionObserverEntry): void {
115
+ this._isPaused = entry.isIntersecting === undefined ? (entry.intersectionRatio === 0) : !entry.isIntersecting;
116
+
117
+ // Terminal was hidden on open
118
+ if (!this._isPaused && !this._charSizeService.hasValidSize) {
119
+ this._charSizeService.measure();
120
+ }
121
+
122
+ if (!this._isPaused && this._needsFullRefresh) {
123
+ this._pausedResizeTask.flush();
124
+ this.refreshRows(0, this._rowCount - 1);
125
+ this._needsFullRefresh = false;
126
+ }
127
+ }
128
+
129
+ public refreshRows(start: number, end: number, isRedrawOnly: boolean = false): void {
130
+ if (this._isPaused) {
131
+ this._needsFullRefresh = true;
132
+ return;
133
+ }
134
+ if (!isRedrawOnly) {
135
+ this._isNextRenderRedrawOnly = false;
136
+ }
137
+ this._renderDebouncer.refresh(start, end, this._rowCount);
138
+ }
139
+
140
+ private _renderRows(start: number, end: number): void {
141
+ if (!this._renderer.value) {
142
+ return;
143
+ }
144
+
145
+ // Since this is debounced, a resize event could have happened between the time a refresh was
146
+ // requested and when this triggers. Clamp the values of start and end to ensure they're valid
147
+ // given the current viewport state.
148
+ start = Math.min(start, this._rowCount - 1);
149
+ end = Math.min(end, this._rowCount - 1);
150
+
151
+ // Render
152
+ this._renderer.value.renderRows(start, end);
153
+
154
+ // Update selection if needed
155
+ if (this._needsSelectionRefresh) {
156
+ this._renderer.value.handleSelectionChanged(this._selectionState.start, this._selectionState.end, this._selectionState.columnSelectMode);
157
+ this._needsSelectionRefresh = false;
158
+ }
159
+
160
+ // Fire render event only if it was not a redraw
161
+ if (!this._isNextRenderRedrawOnly) {
162
+ this._onRenderedViewportChange.fire({ start, end });
163
+ }
164
+ this._onRender.fire({ start, end });
165
+ this._isNextRenderRedrawOnly = true;
166
+ }
167
+
168
+ public resize(cols: number, rows: number): void {
169
+ this._rowCount = rows;
170
+ this._fireOnCanvasResize();
171
+ }
172
+
173
+ private _handleOptionsChanged(): void {
174
+ if (!this._renderer.value) {
175
+ return;
176
+ }
177
+ this.refreshRows(0, this._rowCount - 1);
178
+ this._fireOnCanvasResize();
179
+ }
180
+
181
+ private _fireOnCanvasResize(): void {
182
+ if (!this._renderer.value) {
183
+ return;
184
+ }
185
+ // Don't fire the event if the dimensions haven't changed
186
+ if (this._renderer.value.dimensions.css.canvas.width === this._canvasWidth && this._renderer.value.dimensions.css.canvas.height === this._canvasHeight) {
187
+ return;
188
+ }
189
+ this._onDimensionsChange.fire(this._renderer.value.dimensions);
190
+ }
191
+
192
+ public hasRenderer(): boolean {
193
+ return !!this._renderer.value;
194
+ }
195
+
196
+ public setRenderer(renderer: IRenderer): void {
197
+ this._renderer.value = renderer;
198
+ // If the value was not set, the terminal is being disposed so ignore it
199
+ if (this._renderer.value) {
200
+ this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
201
+
202
+ // Force a refresh
203
+ this._needsSelectionRefresh = true;
204
+ this._fullRefresh();
205
+ }
206
+ }
207
+
208
+ public addRefreshCallback(callback: FrameRequestCallback): number {
209
+ return this._renderDebouncer.addRefreshCallback(callback);
210
+ }
211
+
212
+ private _fullRefresh(): void {
213
+ if (this._isPaused) {
214
+ this._needsFullRefresh = true;
215
+ } else {
216
+ this.refreshRows(0, this._rowCount - 1);
217
+ }
218
+ }
219
+
220
+ public clearTextureAtlas(): void {
221
+ if (!this._renderer.value) {
222
+ return;
223
+ }
224
+ this._renderer.value.clearTextureAtlas?.();
225
+ this._fullRefresh();
226
+ }
227
+
228
+ public handleDevicePixelRatioChange(): void {
229
+ // Force char size measurement as DomMeasureStrategy(getBoundingClientRect) is not stable
230
+ // when devicePixelRatio changes
231
+ this._charSizeService.measure();
232
+
233
+ if (!this._renderer.value) {
234
+ return;
235
+ }
236
+ this._renderer.value.handleDevicePixelRatioChange();
237
+ this.refreshRows(0, this._rowCount - 1);
238
+ }
239
+
240
+ public handleResize(cols: number, rows: number): void {
241
+ if (!this._renderer.value) {
242
+ return;
243
+ }
244
+ if (this._isPaused) {
245
+ this._pausedResizeTask.set(() => this._renderer.value!.handleResize(cols, rows));
246
+ } else {
247
+ this._renderer.value.handleResize(cols, rows);
248
+ }
249
+ this._fullRefresh();
250
+ }
251
+
252
+ // TODO: Is this useful when we have onResize?
253
+ public handleCharSizeChanged(): void {
254
+ this._renderer.value?.handleCharSizeChanged();
255
+ }
256
+
257
+ public handleBlur(): void {
258
+ this._renderer.value?.handleBlur();
259
+ }
260
+
261
+ public handleFocus(): void {
262
+ this._renderer.value?.handleFocus();
263
+ }
264
+
265
+ public handleSelectionChanged(start: [number, number] | undefined, end: [number, number] | undefined, columnSelectMode: boolean): void {
266
+ this._selectionState.start = start;
267
+ this._selectionState.end = end;
268
+ this._selectionState.columnSelectMode = columnSelectMode;
269
+ this._renderer.value?.handleSelectionChanged(start, end, columnSelectMode);
270
+ }
271
+
272
+ public handleCursorMove(): void {
273
+ this._renderer.value?.handleCursorMove();
274
+ }
275
+
276
+ public clear(): void {
277
+ this._renderer.value?.clear();
278
+ }
279
+ }