@wendongfly/zihi 1.1.0 → 1.1.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.
Files changed (157) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/lib/xterm/README.md +27 -14
  3. package/dist/lib/xterm/css/xterm.css +81 -5
  4. package/dist/lib/xterm/lib/xterm.js +1 -1
  5. package/dist/lib/xterm/lib/xterm.js.map +1 -1
  6. package/dist/lib/xterm/lib/xterm.mjs +53 -0
  7. package/dist/lib/xterm/lib/xterm.mjs.map +7 -0
  8. package/dist/lib/xterm/package.json +49 -38
  9. package/dist/lib/xterm/src/browser/AccessibilityManager.ts +185 -50
  10. package/dist/lib/xterm/src/browser/CoreBrowserTerminal.ts +1339 -0
  11. package/dist/lib/xterm/src/browser/Linkifier.ts +403 -0
  12. package/dist/lib/xterm/src/browser/LocalizableStrings.ts +15 -4
  13. package/dist/lib/xterm/src/browser/OscLinkProvider.ts +2 -1
  14. package/dist/lib/xterm/src/browser/RenderDebouncer.ts +6 -5
  15. package/dist/lib/xterm/src/browser/TimeBasedDebouncer.ts +2 -2
  16. package/dist/lib/xterm/src/browser/Types.ts +226 -0
  17. package/dist/lib/xterm/src/browser/Viewport.ts +148 -357
  18. package/dist/lib/xterm/src/browser/decorations/BufferDecorationRenderer.ts +17 -12
  19. package/dist/lib/xterm/src/browser/decorations/OverviewRulerRenderer.ts +47 -52
  20. package/dist/lib/xterm/src/browser/input/CompositionHelper.ts +5 -3
  21. package/dist/lib/xterm/src/browser/input/MoveToCell.ts +3 -1
  22. package/dist/lib/xterm/src/browser/public/Terminal.ts +39 -24
  23. package/dist/lib/xterm/src/browser/renderer/dom/DomRenderer.ts +76 -40
  24. package/dist/lib/xterm/src/browser/renderer/dom/DomRendererRowFactory.ts +47 -23
  25. package/dist/lib/xterm/src/browser/renderer/dom/WidthCache.ts +19 -9
  26. package/dist/lib/xterm/src/browser/renderer/shared/Constants.ts +0 -8
  27. package/dist/lib/xterm/src/browser/renderer/shared/RendererUtils.ts +38 -1
  28. package/dist/lib/xterm/src/browser/renderer/shared/SelectionRenderModel.ts +6 -4
  29. package/dist/lib/xterm/src/browser/renderer/shared/Types.ts +84 -0
  30. package/dist/lib/xterm/src/browser/selection/Types.ts +15 -0
  31. package/dist/lib/xterm/src/browser/services/CharSizeService.ts +57 -32
  32. package/dist/lib/xterm/src/browser/services/CoreBrowserService.ts +108 -4
  33. package/dist/lib/xterm/src/browser/services/LinkProviderService.ts +28 -0
  34. package/dist/lib/xterm/src/browser/services/RenderService.ts +132 -40
  35. package/dist/lib/xterm/src/browser/services/SelectionService.ts +19 -9
  36. package/dist/lib/xterm/src/browser/services/Services.ts +36 -16
  37. package/dist/lib/xterm/src/browser/services/ThemeService.ts +19 -58
  38. package/dist/lib/xterm/src/browser/shared/Constants.ts +8 -0
  39. package/dist/lib/xterm/src/common/CircularList.ts +5 -5
  40. package/dist/lib/xterm/src/common/Color.ts +34 -14
  41. package/dist/lib/xterm/src/common/CoreTerminal.ts +40 -41
  42. package/dist/lib/xterm/src/common/InputHandler.ts +177 -125
  43. package/dist/lib/xterm/src/common/Platform.ts +2 -1
  44. package/dist/lib/xterm/src/common/SortedList.ts +86 -10
  45. package/dist/lib/xterm/src/common/TaskQueue.ts +7 -7
  46. package/dist/lib/xterm/src/common/Types.ts +552 -0
  47. package/dist/lib/xterm/src/common/buffer/AttributeData.ts +15 -0
  48. package/dist/lib/xterm/src/common/buffer/Buffer.ts +15 -7
  49. package/dist/lib/xterm/src/common/buffer/BufferLine.ts +53 -22
  50. package/dist/lib/xterm/src/common/buffer/BufferRange.ts +1 -1
  51. package/dist/lib/xterm/src/common/buffer/BufferReflow.ts +9 -6
  52. package/dist/lib/xterm/src/common/buffer/BufferSet.ts +5 -5
  53. package/dist/lib/xterm/src/common/buffer/Constants.ts +10 -2
  54. package/dist/lib/xterm/src/common/buffer/Marker.ts +4 -4
  55. package/dist/lib/xterm/src/common/buffer/Types.ts +52 -0
  56. package/dist/lib/xterm/src/common/input/Keyboard.ts +2 -27
  57. package/dist/lib/xterm/src/common/input/UnicodeV6.ts +18 -5
  58. package/dist/lib/xterm/src/common/input/WriteBuffer.ts +9 -8
  59. package/dist/lib/xterm/src/common/parser/EscapeSequenceParser.ts +13 -13
  60. package/dist/lib/xterm/src/common/parser/Types.ts +275 -0
  61. package/dist/lib/xterm/src/common/public/AddonManager.ts +1 -1
  62. package/dist/lib/xterm/src/common/public/BufferApiView.ts +1 -1
  63. package/dist/lib/xterm/src/common/public/BufferLineApiView.ts +1 -1
  64. package/dist/lib/xterm/src/common/public/BufferNamespaceApi.ts +4 -4
  65. package/dist/lib/xterm/src/common/public/ParserApi.ts +1 -1
  66. package/dist/lib/xterm/src/common/public/UnicodeApi.ts +1 -1
  67. package/dist/lib/xterm/src/common/services/BufferService.ts +14 -11
  68. package/dist/lib/xterm/src/common/services/CoreMouseService.ts +53 -6
  69. package/dist/lib/xterm/src/common/services/CoreService.ts +13 -8
  70. package/dist/lib/xterm/src/common/services/DecorationService.ts +11 -11
  71. package/dist/lib/xterm/src/common/services/InstantiationService.ts +1 -1
  72. package/dist/lib/xterm/src/common/services/LogService.ts +2 -2
  73. package/dist/lib/xterm/src/common/services/OptionsService.ts +16 -5
  74. package/dist/lib/xterm/src/common/services/ServiceRegistry.ts +1 -1
  75. package/dist/lib/xterm/src/common/services/Services.ts +73 -19
  76. package/dist/lib/xterm/src/common/services/UnicodeService.ts +30 -5
  77. package/dist/lib/xterm/src/vs/base/browser/browser.ts +141 -0
  78. package/dist/lib/xterm/src/vs/base/browser/canIUse.ts +49 -0
  79. package/dist/lib/xterm/src/vs/base/browser/dom.ts +2369 -0
  80. package/dist/lib/xterm/src/vs/base/browser/fastDomNode.ts +316 -0
  81. package/dist/lib/xterm/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
  82. package/dist/lib/xterm/src/vs/base/browser/iframe.ts +135 -0
  83. package/dist/lib/xterm/src/vs/base/browser/keyboardEvent.ts +213 -0
  84. package/dist/lib/xterm/src/vs/base/browser/mouseEvent.ts +229 -0
  85. package/dist/lib/xterm/src/vs/base/browser/touch.ts +372 -0
  86. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
  87. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
  88. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
  89. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
  90. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
  91. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
  92. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
  93. package/dist/lib/xterm/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
  94. package/dist/lib/xterm/src/vs/base/browser/ui/widget.ts +57 -0
  95. package/dist/lib/xterm/src/vs/base/browser/window.ts +14 -0
  96. package/dist/lib/xterm/src/vs/base/common/arrays.ts +887 -0
  97. package/dist/lib/xterm/src/vs/base/common/arraysFind.ts +202 -0
  98. package/dist/lib/xterm/src/vs/base/common/assert.ts +71 -0
  99. package/dist/lib/xterm/src/vs/base/common/async.ts +1992 -0
  100. package/dist/lib/xterm/src/vs/base/common/cancellation.ts +148 -0
  101. package/dist/lib/xterm/src/vs/base/common/charCode.ts +450 -0
  102. package/dist/lib/xterm/src/vs/base/common/collections.ts +140 -0
  103. package/dist/lib/xterm/src/vs/base/common/decorators.ts +130 -0
  104. package/dist/lib/xterm/src/vs/base/common/equals.ts +146 -0
  105. package/dist/lib/xterm/src/vs/base/common/errors.ts +303 -0
  106. package/dist/lib/xterm/src/vs/base/common/event.ts +1778 -0
  107. package/dist/lib/xterm/src/vs/base/common/functional.ts +32 -0
  108. package/dist/lib/xterm/src/vs/base/common/hash.ts +316 -0
  109. package/dist/lib/xterm/src/vs/base/common/iterator.ts +159 -0
  110. package/dist/lib/xterm/src/vs/base/common/keyCodes.ts +526 -0
  111. package/dist/lib/xterm/src/vs/base/common/keybindings.ts +284 -0
  112. package/dist/lib/xterm/src/vs/base/common/lazy.ts +47 -0
  113. package/dist/lib/xterm/src/vs/base/common/lifecycle.ts +801 -0
  114. package/dist/lib/xterm/src/vs/base/common/linkedList.ts +142 -0
  115. package/dist/lib/xterm/src/vs/base/common/map.ts +202 -0
  116. package/dist/lib/xterm/src/vs/base/common/numbers.ts +98 -0
  117. package/dist/lib/xterm/src/vs/base/common/observable.ts +76 -0
  118. package/dist/lib/xterm/src/vs/base/common/observableInternal/api.ts +31 -0
  119. package/dist/lib/xterm/src/vs/base/common/observableInternal/autorun.ts +281 -0
  120. package/dist/lib/xterm/src/vs/base/common/observableInternal/base.ts +489 -0
  121. package/dist/lib/xterm/src/vs/base/common/observableInternal/debugName.ts +145 -0
  122. package/dist/lib/xterm/src/vs/base/common/observableInternal/derived.ts +428 -0
  123. package/dist/lib/xterm/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
  124. package/dist/lib/xterm/src/vs/base/common/observableInternal/logging.ts +328 -0
  125. package/dist/lib/xterm/src/vs/base/common/observableInternal/promise.ts +209 -0
  126. package/dist/lib/xterm/src/vs/base/common/observableInternal/utils.ts +610 -0
  127. package/dist/lib/xterm/src/vs/base/common/platform.ts +281 -0
  128. package/dist/lib/xterm/src/vs/base/common/scrollable.ts +522 -0
  129. package/dist/lib/xterm/src/vs/base/common/sequence.ts +34 -0
  130. package/dist/lib/xterm/src/vs/base/common/stopwatch.ts +43 -0
  131. package/dist/lib/xterm/src/vs/base/common/strings.ts +557 -0
  132. package/dist/lib/xterm/src/vs/base/common/symbols.ts +9 -0
  133. package/dist/lib/xterm/src/vs/base/common/uint.ts +59 -0
  134. package/dist/lib/xterm/src/vs/patches/nls.ts +90 -0
  135. package/dist/lib/xterm/src/vs/typings/base-common.d.ts +20 -0
  136. package/dist/lib/xterm/src/vs/typings/require.d.ts +42 -0
  137. package/dist/lib/xterm/src/vs/typings/vscode-globals-nls.d.ts +36 -0
  138. package/dist/lib/xterm/src/vs/typings/vscode-globals-product.d.ts +33 -0
  139. package/dist/lib/xterm/typings/xterm.d.ts +156 -43
  140. package/dist/lib/xterm-fit/README.md +5 -5
  141. package/dist/lib/xterm-fit/lib/addon-fit.js +2 -0
  142. package/dist/lib/xterm-fit/lib/addon-fit.js.map +1 -0
  143. package/dist/lib/xterm-fit/lib/addon-fit.mjs +18 -0
  144. package/dist/lib/xterm-fit/lib/addon-fit.mjs.map +7 -0
  145. package/dist/lib/xterm-fit/package.json +9 -9
  146. package/dist/lib/xterm-fit/src/FitAddon.ts +7 -4
  147. package/dist/lib/xterm-fit/typings/addon-fit.d.ts +55 -0
  148. package/dist/lib/xterm-links/README.md +5 -5
  149. package/dist/lib/xterm-links/lib/addon-web-links.js +2 -0
  150. package/dist/lib/xterm-links/lib/addon-web-links.js.map +1 -0
  151. package/dist/lib/xterm-links/lib/addon-web-links.mjs +18 -0
  152. package/dist/lib/xterm-links/lib/addon-web-links.mjs.map +7 -0
  153. package/dist/lib/xterm-links/package.json +9 -9
  154. package/dist/lib/xterm-links/src/WebLinkProvider.ts +16 -15
  155. package/dist/lib/xterm-links/src/WebLinksAddon.ts +4 -3
  156. package/dist/lib/xterm-links/typings/addon-web-links.d.ts +57 -0
  157. package/package.json +5 -6
@@ -4,11 +4,14 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
 
6
6
  import { ColorZoneStore, IColorZone, IColorZoneStore } from 'browser/decorations/ColorZoneStore';
7
- import { addDisposableDomListener } from 'browser/Lifecycle';
8
- import { ICoreBrowserService, IRenderService } from 'browser/services/Services';
9
- import { Disposable, toDisposable } from 'common/Lifecycle';
7
+ import { ICoreBrowserService, IRenderService, IThemeService } from 'browser/services/Services';
8
+ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
10
9
  import { IBufferService, IDecorationService, IOptionsService } from 'common/services/Services';
11
10
 
11
+ const enum Constants {
12
+ OVERVIEW_RULER_BORDER_WIDTH = 1
13
+ }
14
+
12
15
  // Helper objects to avoid excessive calculation and garbage collection during rendering. These are
13
16
  // static values for each render and can be accessed using the decoration position as the key.
14
17
  const drawHeight = {
@@ -35,7 +38,7 @@ export class OverviewRulerRenderer extends Disposable {
35
38
  private readonly _ctx: CanvasRenderingContext2D;
36
39
  private readonly _colorZoneStore: IColorZoneStore = new ColorZoneStore();
37
40
  private get _width(): number {
38
- return this._optionsService.options.overviewRulerWidth || 0;
41
+ return this._optionsService.options.overviewRuler?.width || 0;
39
42
  }
40
43
  private _animationFrame: number | undefined;
41
44
 
@@ -52,75 +55,55 @@ export class OverviewRulerRenderer extends Disposable {
52
55
  @IDecorationService private readonly _decorationService: IDecorationService,
53
56
  @IRenderService private readonly _renderService: IRenderService,
54
57
  @IOptionsService private readonly _optionsService: IOptionsService,
55
- @ICoreBrowserService private readonly _coreBrowseService: ICoreBrowserService
58
+ @IThemeService private readonly _themeService: IThemeService,
59
+ @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService
56
60
  ) {
57
61
  super();
58
- this._canvas = document.createElement('canvas');
62
+ this._canvas = this._coreBrowserService.mainDocument.createElement('canvas');
59
63
  this._canvas.classList.add('xterm-decoration-overview-ruler');
60
64
  this._refreshCanvasDimensions();
61
65
  this._viewportElement.parentElement?.insertBefore(this._canvas, this._viewportElement);
66
+ this._register(toDisposable(() => this._canvas?.remove()));
67
+
62
68
  const ctx = this._canvas.getContext('2d');
63
69
  if (!ctx) {
64
70
  throw new Error('Ctx cannot be null');
65
71
  } else {
66
72
  this._ctx = ctx;
67
73
  }
68
- this._registerDecorationListeners();
69
- this._registerBufferChangeListeners();
70
- this._registerDimensionChangeListeners();
71
- this.register(toDisposable(() => {
72
- this._canvas?.remove();
73
- }));
74
- }
75
74
 
76
- /**
77
- * On decoration add or remove, redraw
78
- */
79
- private _registerDecorationListeners(): void {
80
- this.register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));
81
- this.register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));
82
- }
75
+ this._register(this._decorationService.onDecorationRegistered(() => this._queueRefresh(undefined, true)));
76
+ this._register(this._decorationService.onDecorationRemoved(() => this._queueRefresh(undefined, true)));
83
77
 
84
- /**
85
- * On buffer change, redraw
86
- * and hide the canvas if the alt buffer is active
87
- */
88
- private _registerBufferChangeListeners(): void {
89
- this.register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));
90
- this.register(this._bufferService.buffers.onBufferActivate(() => {
78
+ this._register(this._renderService.onRenderedViewportChange(() => this._queueRefresh()));
79
+ this._register(this._bufferService.buffers.onBufferActivate(() => {
91
80
  this._canvas!.style.display = this._bufferService.buffer === this._bufferService.buffers.alt ? 'none' : 'block';
92
81
  }));
93
- this.register(this._bufferService.onScroll(() => {
82
+ this._register(this._bufferService.onScroll(() => {
94
83
  if (this._lastKnownBufferLength !== this._bufferService.buffers.normal.lines.length) {
95
84
  this._refreshDrawHeightConstants();
96
85
  this._refreshColorZonePadding();
97
86
  }
98
87
  }));
99
- }
100
- /**
101
- * On dimension change, update canvas dimensions
102
- * and then redraw
103
- */
104
- private _registerDimensionChangeListeners(): void {
105
- // container height changed
106
- this.register(this._renderService.onRender((): void => {
88
+
89
+ // Container height changed
90
+ this._register(this._renderService.onRender((): void => {
107
91
  if (!this._containerHeight || this._containerHeight !== this._screenElement.clientHeight) {
108
92
  this._queueRefresh(true);
109
93
  this._containerHeight = this._screenElement.clientHeight;
110
94
  }
111
95
  }));
112
- // overview ruler width changed
113
- this.register(this._optionsService.onSpecificOptionChange('overviewRulerWidth', () => this._queueRefresh(true)));
114
- // device pixel ratio changed
115
- this.register(addDisposableDomListener(this._coreBrowseService.window, 'resize', () => this._queueRefresh(true)));
116
- // set the canvas dimensions
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()));
117
100
  this._queueRefresh(true);
118
101
  }
119
102
 
120
103
  private _refreshDrawConstants(): void {
121
104
  // width
122
- const outerWidth = Math.floor(this._canvas.width / 3);
123
- const innerWidth = Math.ceil(this._canvas.width / 3);
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);
124
107
  drawWidth.full = this._canvas.width;
125
108
  drawWidth.left = outerWidth;
126
109
  drawWidth.center = innerWidth;
@@ -128,18 +111,18 @@ export class OverviewRulerRenderer extends Disposable {
128
111
  // height
129
112
  this._refreshDrawHeightConstants();
130
113
  // x
131
- drawX.full = 0;
132
- drawX.left = 0;
133
- drawX.center = drawWidth.left;
134
- drawX.right = drawWidth.left + drawWidth.center;
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;
135
118
  }
136
119
 
137
120
  private _refreshDrawHeightConstants(): void {
138
- drawHeight.full = Math.round(2 * this._coreBrowseService.dpr);
121
+ drawHeight.full = Math.round(2 * this._coreBrowserService.dpr);
139
122
  // Calculate actual pixels per line
140
123
  const pixelsPerLine = this._canvas.height / this._bufferService.buffer.lines.length;
141
124
  // Clamp actual pixels within a range
142
- const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowseService.dpr);
125
+ const nonFullHeight = Math.round(Math.max(Math.min(pixelsPerLine, 12), 6) * this._coreBrowserService.dpr);
143
126
  drawHeight.left = nonFullHeight;
144
127
  drawHeight.center = nonFullHeight;
145
128
  drawHeight.right = nonFullHeight;
@@ -157,9 +140,9 @@ export class OverviewRulerRenderer extends Disposable {
157
140
 
158
141
  private _refreshCanvasDimensions(): void {
159
142
  this._canvas.style.width = `${this._width}px`;
160
- this._canvas.width = Math.round(this._width * this._coreBrowseService.dpr);
143
+ this._canvas.width = Math.round(this._width * this._coreBrowserService.dpr);
161
144
  this._canvas.style.height = `${this._screenElement.clientHeight}px`;
162
- this._canvas.height = Math.round(this._screenElement.clientHeight * this._coreBrowseService.dpr);
145
+ this._canvas.height = Math.round(this._screenElement.clientHeight * this._coreBrowserService.dpr);
163
146
  this._refreshDrawConstants();
164
147
  this._refreshColorZonePadding();
165
148
  }
@@ -174,6 +157,7 @@ export class OverviewRulerRenderer extends Disposable {
174
157
  this._colorZoneStore.addDecoration(decoration);
175
158
  }
176
159
  this._ctx.lineWidth = 1;
160
+ this._renderRulerOutline();
177
161
  const zones = this._colorZoneStore.zones;
178
162
  for (const zone of zones) {
179
163
  if (zone.position !== 'full') {
@@ -189,6 +173,17 @@ export class OverviewRulerRenderer extends Disposable {
189
173
  this._shouldUpdateAnchor = false;
190
174
  }
191
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
+
192
187
  private _renderColorZone(zone: IColorZone): void {
193
188
  this._ctx.fillStyle = zone.color;
194
189
  this._ctx.fillRect(
@@ -211,7 +206,7 @@ export class OverviewRulerRenderer extends Disposable {
211
206
  if (this._animationFrame !== undefined) {
212
207
  return;
213
208
  }
214
- this._animationFrame = this._coreBrowseService.window.requestAnimationFrame(() => {
209
+ this._animationFrame = this._coreBrowserService.window.requestAnimationFrame(() => {
215
210
  this._refreshDecorations();
216
211
  this._animationFrame = undefined;
217
212
  });
@@ -93,7 +93,8 @@ export class CompositionHelper {
93
93
  */
94
94
  public keydown(ev: KeyboardEvent): boolean {
95
95
  if (this._isComposing || this._isSendingComposition) {
96
- if (ev.keyCode === 229) {
96
+ if (ev.keyCode === 20 || ev.keyCode === 229) {
97
+ // 20 is CapsLock, 229 is Enter
97
98
  // Continue composing if the keyCode is the "composition character"
98
99
  return false;
99
100
  }
@@ -159,8 +160,9 @@ export class CompositionHelper {
159
160
  // otherwise input characters can be duplicated. (Issue #3191)
160
161
  currentCompositionPosition.start += this._dataAlreadySent.length;
161
162
  if (this._isComposing) {
162
- // Use the end position to get the string if a new composition has started.
163
- input = this._textarea.value.substring(currentCompositionPosition.start, currentCompositionPosition.end);
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);
164
166
  } else {
165
167
  // Don't use the end position here in order to pick up any characters after the
166
168
  // composition has finished, for example when typing a non-composition character
@@ -199,7 +199,9 @@ function bufferLine(
199
199
  let currentRow = startRow;
200
200
  let bufferStr = '';
201
201
 
202
- while (currentCol !== endCol || currentRow !== endRow) {
202
+ while ((currentCol !== endCol || currentRow !== endRow) &&
203
+ currentRow >= 0 &&
204
+ currentRow < bufferService.buffer.lines.length) {
203
205
  currentCol += forward ? 1 : -1;
204
206
 
205
207
  if (forward && currentCol > bufferService.cols - 1) {
@@ -4,22 +4,24 @@
4
4
  */
5
5
 
6
6
  import * as Strings from 'browser/LocalizableStrings';
7
- import { Terminal as TerminalCore } from 'browser/Terminal';
7
+ import { CoreBrowserTerminal as TerminalCore } from 'browser/CoreBrowserTerminal';
8
8
  import { IBufferRange, ITerminal } from 'browser/Types';
9
- import { IEvent } from 'common/EventEmitter';
10
- import { Disposable } from 'common/Lifecycle';
9
+ import { Disposable } from 'vs/base/common/lifecycle';
11
10
  import { ITerminalOptions } from 'common/Types';
12
11
  import { AddonManager } from 'common/public/AddonManager';
13
12
  import { BufferNamespaceApi } from 'common/public/BufferNamespaceApi';
14
13
  import { ParserApi } from 'common/public/ParserApi';
15
14
  import { UnicodeApi } from 'common/public/UnicodeApi';
16
- import { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from 'xterm';
15
+ import { IBufferNamespace as IBufferNamespaceApi, IDecoration, IDecorationOptions, IDisposable, ILinkProvider, ILocalizableStrings, IMarker, IModes, IParser, ITerminalAddon, Terminal as ITerminalApi, ITerminalInitOnlyOptions, IUnicodeHandling } from '@xterm/xterm';
16
+ import type { Event } from 'vs/base/common/event';
17
17
 
18
18
  /**
19
19
  * The set of options that only have an effect when set in the Terminal constructor.
20
20
  */
21
21
  const CONSTRUCTOR_ONLY_OPTIONS = ['cols', 'rows'];
22
22
 
23
+ let $value = 0;
24
+
23
25
  export class Terminal extends Disposable implements ITerminalApi {
24
26
  private _core: ITerminal;
25
27
  private _addonManager: AddonManager;
@@ -30,8 +32,8 @@ export class Terminal extends Disposable implements ITerminalApi {
30
32
  constructor(options?: ITerminalOptions & ITerminalInitOnlyOptions) {
31
33
  super();
32
34
 
33
- this._core = this.register(new TerminalCore(options));
34
- this._addonManager = this.register(new AddonManager());
35
+ this._core = this._register(new TerminalCore(options));
36
+ this._addonManager = this._register(new AddonManager());
35
37
 
36
38
  this._publicOptions = { ... this._core.options };
37
39
  const getter = (propName: string): any => {
@@ -66,18 +68,18 @@ export class Terminal extends Disposable implements ITerminalApi {
66
68
  }
67
69
  }
68
70
 
69
- public get onBell(): IEvent<void> { return this._core.onBell; }
70
- public get onBinary(): IEvent<string> { return this._core.onBinary; }
71
- public get onCursorMove(): IEvent<void> { return this._core.onCursorMove; }
72
- public get onData(): IEvent<string> { return this._core.onData; }
73
- public get onKey(): IEvent<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }
74
- public get onLineFeed(): IEvent<void> { return this._core.onLineFeed; }
75
- public get onRender(): IEvent<{ start: number, end: number }> { return this._core.onRender; }
76
- public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; }
77
- public get onScroll(): IEvent<number> { return this._core.onScroll; }
78
- public get onSelectionChange(): IEvent<void> { return this._core.onSelectionChange; }
79
- public get onTitleChange(): IEvent<string> { return this._core.onTitleChange; }
80
- public get onWriteParsed(): IEvent<void> { return this._core.onWriteParsed; }
71
+ public get onBell(): Event<void> { return this._core.onBell; }
72
+ public get onBinary(): Event<string> { return this._core.onBinary; }
73
+ public get onCursorMove(): Event<void> { return this._core.onCursorMove; }
74
+ public get onData(): Event<string> { return this._core.onData; }
75
+ public get onKey(): Event<{ key: string, domEvent: KeyboardEvent }> { return this._core.onKey; }
76
+ public get onLineFeed(): Event<void> { return this._core.onLineFeed; }
77
+ public get onRender(): Event<{ start: number, end: number }> { return this._core.onRender; }
78
+ public get onResize(): Event<{ cols: number, rows: number }> { return this._core.onResize; }
79
+ public get onScroll(): Event<number> { return this._core.onScroll; }
80
+ public get onSelectionChange(): Event<void> { return this._core.onSelectionChange; }
81
+ public get onTitleChange(): Event<string> { return this._core.onTitleChange; }
82
+ public get onWriteParsed(): Event<void> { return this._core.onWriteParsed; }
81
83
 
82
84
  public get element(): HTMLElement | undefined { return this._core.element; }
83
85
  public get parser(): IParser {
@@ -95,7 +97,7 @@ export class Terminal extends Disposable implements ITerminalApi {
95
97
  public get cols(): number { return this._core.cols; }
96
98
  public get buffer(): IBufferNamespaceApi {
97
99
  if (!this._buffer) {
98
- this._buffer = this.register(new BufferNamespaceApi(this._core));
100
+ this._buffer = this._register(new BufferNamespaceApi(this._core));
99
101
  }
100
102
  return this._buffer;
101
103
  }
@@ -121,6 +123,7 @@ export class Terminal extends Disposable implements ITerminalApi {
121
123
  originMode: m.origin,
122
124
  reverseWraparoundMode: m.reverseWraparound,
123
125
  sendFocusMode: m.sendFocus,
126
+ synchronizedOutputMode: m.synchronizedOutput,
124
127
  wraparoundMode: m.wraparound
125
128
  };
126
129
  }
@@ -138,6 +141,9 @@ export class Terminal extends Disposable implements ITerminalApi {
138
141
  public focus(): void {
139
142
  this._core.focus();
140
143
  }
144
+ public input(data: string, wasUserInput: boolean = true): void {
145
+ this._core.input(data, wasUserInput);
146
+ }
141
147
  public resize(columns: number, rows: number): void {
142
148
  this._verifyIntegers(columns, rows);
143
149
  this._core.resize(columns, rows);
@@ -148,6 +154,9 @@ export class Terminal extends Disposable implements ITerminalApi {
148
154
  public attachCustomKeyEventHandler(customKeyEventHandler: (event: KeyboardEvent) => boolean): void {
149
155
  this._core.attachCustomKeyEventHandler(customKeyEventHandler);
150
156
  }
157
+ public attachCustomWheelEventHandler(customWheelEventHandler: (event: WheelEvent) => boolean): void {
158
+ this._core.attachCustomWheelEventHandler(customWheelEventHandler);
159
+ }
151
160
  public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
152
161
  return this._core.registerLinkProvider(linkProvider);
153
162
  }
@@ -239,20 +248,26 @@ export class Terminal extends Disposable implements ITerminalApi {
239
248
  this._addonManager.loadAddon(this, addon);
240
249
  }
241
250
  public static get strings(): ILocalizableStrings {
242
- return Strings;
251
+ // A wrapper is required here because esbuild prevents setting an `export let`
252
+ return {
253
+ get promptLabel(): string { return Strings.promptLabel.get(); },
254
+ set promptLabel(value: string) { Strings.promptLabel.set(value); },
255
+ get tooMuchOutput(): string { return Strings.tooMuchOutput.get(); },
256
+ set tooMuchOutput(value: string) { Strings.tooMuchOutput.set(value); }
257
+ };
243
258
  }
244
259
 
245
260
  private _verifyIntegers(...values: number[]): void {
246
- for (const value of values) {
247
- if (value === Infinity || isNaN(value) || value % 1 !== 0) {
261
+ for ($value of values) {
262
+ if ($value === Infinity || isNaN($value) || $value % 1 !== 0) {
248
263
  throw new Error('This API only accepts integers');
249
264
  }
250
265
  }
251
266
  }
252
267
 
253
268
  private _verifyPositiveIntegers(...values: number[]): void {
254
- for (const value of values) {
255
- if (value && (value === Infinity || isNaN(value) || value % 1 !== 0 || value < 0)) {
269
+ for ($value of values) {
270
+ if ($value && ($value === Infinity || isNaN($value) || $value % 1 !== 0 || $value < 0)) {
256
271
  throw new Error('This API only accepts positive integers');
257
272
  }
258
273
  }
@@ -7,13 +7,14 @@ import { DomRendererRowFactory, RowCss } from 'browser/renderer/dom/DomRendererR
7
7
  import { WidthCache } from 'browser/renderer/dom/WidthCache';
8
8
  import { INVERTED_DEFAULT_COLOR } from 'browser/renderer/shared/Constants';
9
9
  import { createRenderDimensions } from 'browser/renderer/shared/RendererUtils';
10
- import { IRenderDimensions, IRenderer, IRequestRedrawEvent } from 'browser/renderer/shared/Types';
10
+ import { createSelectionRenderModel } from 'browser/renderer/shared/SelectionRenderModel';
11
+ import { IRenderDimensions, IRenderer, IRequestRedrawEvent, ISelectionRenderModel } from 'browser/renderer/shared/Types';
11
12
  import { ICharSizeService, ICoreBrowserService, IThemeService } from 'browser/services/Services';
12
- import { ILinkifier2, ILinkifierEvent, ReadonlyColorSet } from 'browser/Types';
13
+ import { ILinkifier2, ILinkifierEvent, ITerminal, ReadonlyColorSet } from 'browser/Types';
13
14
  import { color } from 'common/Color';
14
- import { EventEmitter } from 'common/EventEmitter';
15
- import { Disposable, toDisposable } from 'common/Lifecycle';
16
- import { IBufferService, IInstantiationService, IOptionsService } from 'common/services/Services';
15
+ import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
16
+ import { IBufferService, ICoreService, IInstantiationService, IOptionsService } from 'common/services/Services';
17
+ import { Emitter } from 'vs/base/common/event';
17
18
 
18
19
 
19
20
  const TERMINAL_CLASS_PREFIX = 'xterm-dom-renderer-owner-';
@@ -25,11 +26,10 @@ const SELECTION_CLASS = 'xterm-selection';
25
26
 
26
27
  let nextTerminalId = 1;
27
28
 
28
-
29
29
  /**
30
- * A fallback renderer for when canvas is slow. This is not meant to be
31
- * particularly fast or feature complete, more just stable and usable for when
32
- * canvas is not an option.
30
+ * The standard renderer and fallback for when the webgl addon is slow. This is not meant to be
31
+ * particularly fast and will even lack some features such as custom glyphs, hoever this is more
32
+ * reliable as webgl may not work on some machines.
33
33
  */
34
34
  export class DomRenderer extends Disposable implements IRenderer {
35
35
  private _rowFactory: DomRendererRowFactory;
@@ -41,38 +41,43 @@ export class DomRenderer extends Disposable implements IRenderer {
41
41
  private _rowElements: HTMLElement[] = [];
42
42
  private _selectionContainer: HTMLElement;
43
43
  private _widthCache: WidthCache;
44
+ private _selectionRenderModel: ISelectionRenderModel = createSelectionRenderModel();
44
45
 
45
46
  public dimensions: IRenderDimensions;
46
47
 
47
- public readonly onRequestRedraw = this.register(new EventEmitter<IRequestRedrawEvent>()).event;
48
+ public readonly onRequestRedraw = this._register(new Emitter<IRequestRedrawEvent>()).event;
48
49
 
49
50
  constructor(
51
+ private readonly _terminal: ITerminal,
52
+ private readonly _document: Document,
50
53
  private readonly _element: HTMLElement,
51
54
  private readonly _screenElement: HTMLElement,
52
55
  private readonly _viewportElement: HTMLElement,
56
+ private readonly _helperContainer: HTMLElement,
53
57
  private readonly _linkifier2: ILinkifier2,
54
58
  @IInstantiationService instantiationService: IInstantiationService,
55
59
  @ICharSizeService private readonly _charSizeService: ICharSizeService,
56
60
  @IOptionsService private readonly _optionsService: IOptionsService,
57
61
  @IBufferService private readonly _bufferService: IBufferService,
62
+ @ICoreService private readonly _coreService: ICoreService,
58
63
  @ICoreBrowserService private readonly _coreBrowserService: ICoreBrowserService,
59
64
  @IThemeService private readonly _themeService: IThemeService
60
65
  ) {
61
66
  super();
62
- this._rowContainer = document.createElement('div');
67
+ this._rowContainer = this._document.createElement('div');
63
68
  this._rowContainer.classList.add(ROW_CONTAINER_CLASS);
64
69
  this._rowContainer.style.lineHeight = 'normal';
65
70
  this._rowContainer.setAttribute('aria-hidden', 'true');
66
71
  this._refreshRowElements(this._bufferService.cols, this._bufferService.rows);
67
- this._selectionContainer = document.createElement('div');
72
+ this._selectionContainer = this._document.createElement('div');
68
73
  this._selectionContainer.classList.add(SELECTION_CLASS);
69
74
  this._selectionContainer.setAttribute('aria-hidden', 'true');
70
75
 
71
76
  this.dimensions = createRenderDimensions();
72
77
  this._updateDimensions();
73
- this.register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));
78
+ this._register(this._optionsService.onOptionChange(() => this._handleOptionsChanged()));
74
79
 
75
- this.register(this._themeService.onChangeColors(e => this._injectCss(e)));
80
+ this._register(this._themeService.onChangeColors(e => this._injectCss(e)));
76
81
  this._injectCss(this._themeService.colors);
77
82
 
78
83
  this._rowFactory = instantiationService.createInstance(DomRendererRowFactory, document);
@@ -81,10 +86,10 @@ export class DomRenderer extends Disposable implements IRenderer {
81
86
  this._screenElement.appendChild(this._rowContainer);
82
87
  this._screenElement.appendChild(this._selectionContainer);
83
88
 
84
- this.register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));
85
- this.register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));
89
+ this._register(this._linkifier2.onShowLinkUnderline(e => this._handleLinkHover(e)));
90
+ this._register(this._linkifier2.onHideLinkUnderline(e => this._handleLinkLeave(e)));
86
91
 
87
- this.register(toDisposable(() => {
92
+ this._register(toDisposable(() => {
88
93
  this._element.classList.remove(TERMINAL_CLASS_PREFIX + this._terminalClass);
89
94
 
90
95
  // Outside influences such as React unmounts may manipulate the DOM before our disposal.
@@ -96,7 +101,7 @@ export class DomRenderer extends Disposable implements IRenderer {
96
101
  this._dimensionsStyleElement.remove();
97
102
  }));
98
103
 
99
- this._widthCache = new WidthCache(document);
104
+ this._widthCache = new WidthCache(this._document, this._helperContainer);
100
105
  this._widthCache.setFont(
101
106
  this._optionsService.rawOptions.fontFamily,
102
107
  this._optionsService.rawOptions.fontSize,
@@ -130,7 +135,7 @@ export class DomRenderer extends Disposable implements IRenderer {
130
135
  }
131
136
 
132
137
  if (!this._dimensionsStyleElement) {
133
- this._dimensionsStyleElement = document.createElement('style');
138
+ this._dimensionsStyleElement = this._document.createElement('style');
134
139
  this._screenElement.appendChild(this._dimensionsStyleElement);
135
140
  }
136
141
 
@@ -150,13 +155,17 @@ export class DomRenderer extends Disposable implements IRenderer {
150
155
 
151
156
  private _injectCss(colors: ReadonlyColorSet): void {
152
157
  if (!this._themeStyleElement) {
153
- this._themeStyleElement = document.createElement('style');
158
+ this._themeStyleElement = this._document.createElement('style');
154
159
  this._screenElement.appendChild(this._themeStyleElement);
155
160
  }
156
161
 
157
162
  // Base CSS
158
163
  let styles =
159
164
  `${this._terminalSelector} .${ROW_CONTAINER_CLASS} {` +
165
+ // Disabling pointer events circumvents a browser behavior that prevents `click` events from
166
+ // being delivered if the target element is replaced during the click. This happened due to
167
+ // refresh() being called during the mousedown handler to start a selection.
168
+ ` pointer-events: none;` +
160
169
  ` color: ${colors.foreground.css};` +
161
170
  ` font-family: ${this._optionsService.rawOptions.fontFamily};` +
162
171
  ` font-size: ${this._optionsService.rawOptions.fontSize}px;` +
@@ -179,14 +188,23 @@ export class DomRenderer extends Disposable implements IRenderer {
179
188
  ` font-style: italic;` +
180
189
  `}`;
181
190
  // Blink animation
191
+ const blinkAnimationUnderlineId = `blink_underline_${this._terminalClass}`;
192
+ const blinkAnimationBarId = `blink_bar_${this._terminalClass}`;
193
+ const blinkAnimationBlockId = `blink_block_${this._terminalClass}`;
182
194
  styles +=
183
- `@keyframes blink_box_shadow` + `_` + this._terminalClass + ` {` +
195
+ `@keyframes ${blinkAnimationUnderlineId} {` +
184
196
  ` 50% {` +
185
197
  ` border-bottom-style: hidden;` +
186
198
  ` }` +
187
199
  `}`;
188
200
  styles +=
189
- `@keyframes blink_block` + `_` + this._terminalClass + ` {` +
201
+ `@keyframes ${blinkAnimationBarId} {` +
202
+ ` 50% {` +
203
+ ` box-shadow: none;` +
204
+ ` }` +
205
+ `}`;
206
+ styles +=
207
+ `@keyframes ${blinkAnimationBlockId} {` +
190
208
  ` 0% {` +
191
209
  ` background-color: ${colors.cursor.css};` +
192
210
  ` color: ${colors.cursorAccent.css};` +
@@ -198,16 +216,26 @@ export class DomRenderer extends Disposable implements IRenderer {
198
216
  `}`;
199
217
  // Cursor
200
218
  styles +=
201
- `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}:not(.${RowCss.CURSOR_STYLE_BLOCK_CLASS}) {` +
202
- ` animation: blink_box_shadow` + `_` + this._terminalClass + ` 1s step-end infinite;` +
219
+ `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_UNDERLINE_CLASS} {` +
220
+ ` animation: ${blinkAnimationUnderlineId} 1s step-end infinite;` +
221
+ `}` +
222
+ `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BAR_CLASS} {` +
223
+ ` animation: ${blinkAnimationBarId} 1s step-end infinite;` +
203
224
  `}` +
204
225
  `${this._terminalSelector} .${ROW_CONTAINER_CLASS}.${FOCUS_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_BLINK_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
205
- ` animation: blink_block` + `_` + this._terminalClass + ` 1s step-end infinite;` +
226
+ ` animation: ${blinkAnimationBlockId} 1s step-end infinite;` +
206
227
  `}` +
228
+ // !important helps fix an issue where the cursor will not render on top of the selection,
229
+ // however it's very hard to fix this issue and retain the blink animation without the use of
230
+ // !important. So this edge case fails when cursor blink is on.
207
231
  `${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
208
232
  ` background-color: ${colors.cursor.css};` +
209
233
  ` color: ${colors.cursorAccent.css};` +
210
234
  `}` +
235
+ `${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS}:not(.${RowCss.CURSOR_BLINK_CLASS}) {` +
236
+ ` background-color: ${colors.cursor.css} !important;` +
237
+ ` color: ${colors.cursorAccent.css} !important;` +
238
+ `}` +
211
239
  `${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +
212
240
  ` outline: 1px solid ${colors.cursor.css};` +
213
241
  ` outline-offset: -1px;` +
@@ -276,7 +304,7 @@ export class DomRenderer extends Disposable implements IRenderer {
276
304
  private _refreshRowElements(cols: number, rows: number): void {
277
305
  // Add missing elements
278
306
  for (let i = this._rowElements.length; i <= rows; i++) {
279
- const row = document.createElement('div');
307
+ const row = this._document.createElement('div');
280
308
  this._rowContainer.appendChild(row);
281
309
  this._rowElements.push(row);
282
310
  }
@@ -289,6 +317,7 @@ export class DomRenderer extends Disposable implements IRenderer {
289
317
  public handleResize(cols: number, rows: number): void {
290
318
  this._refreshRowElements(cols, rows);
291
319
  this._updateDimensions();
320
+ this.handleSelectionChanged(this._selectionRenderModel.selectionStart, this._selectionRenderModel.selectionEnd, this._selectionRenderModel.columnSelectMode);
292
321
  }
293
322
 
294
323
  public handleCharSizeChanged(): void {
@@ -299,6 +328,7 @@ export class DomRenderer extends Disposable implements IRenderer {
299
328
 
300
329
  public handleBlur(): void {
301
330
  this._rowContainer.classList.remove(FOCUS_CLASS);
331
+ this.renderRows(0, this._bufferService.rows - 1);
302
332
  }
303
333
 
304
334
  public handleFocus(): void {
@@ -317,19 +347,19 @@ export class DomRenderer extends Disposable implements IRenderer {
317
347
  return;
318
348
  }
319
349
 
320
- // Translate from buffer position to viewport position
321
- const viewportStartRow = start[1] - this._bufferService.buffer.ydisp;
322
- const viewportEndRow = end[1] - this._bufferService.buffer.ydisp;
323
- const viewportCappedStartRow = Math.max(viewportStartRow, 0);
324
- const viewportCappedEndRow = Math.min(viewportEndRow, this._bufferService.rows - 1);
325
-
326
- // No need to draw the selection
327
- if (viewportCappedStartRow >= this._bufferService.rows || viewportCappedEndRow < 0) {
350
+ this._selectionRenderModel.update(this._terminal, start, end, columnSelectMode);
351
+ if (!this._selectionRenderModel.hasSelection) {
328
352
  return;
329
353
  }
330
354
 
355
+ // Translate from buffer position to viewport position
356
+ const viewportStartRow = this._selectionRenderModel.viewportStartRow;
357
+ const viewportEndRow = this._selectionRenderModel.viewportEndRow;
358
+ const viewportCappedStartRow = this._selectionRenderModel.viewportCappedStartRow;
359
+ const viewportCappedEndRow = this._selectionRenderModel.viewportCappedEndRow;
360
+
331
361
  // Create the selections
332
- const documentFragment = document.createDocumentFragment();
362
+ const documentFragment = this._document.createDocumentFragment();
333
363
 
334
364
  if (columnSelectMode) {
335
365
  const isXFlipped = start[0] > end[0];
@@ -361,11 +391,17 @@ export class DomRenderer extends Disposable implements IRenderer {
361
391
  * @param colEnd The end columns.
362
392
  */
363
393
  private _createSelectionElement(row: number, colStart: number, colEnd: number, rowCount: number = 1): HTMLElement {
364
- const element = document.createElement('div');
394
+ const element = this._document.createElement('div');
395
+ const left = colStart * this.dimensions.css.cell.width;
396
+ let width = this.dimensions.css.cell.width * (colEnd - colStart);
397
+ if (left + width > this.dimensions.css.canvas.width) {
398
+ width = this.dimensions.css.canvas.width - left;
399
+ }
400
+
365
401
  element.style.height = `${rowCount * this.dimensions.css.cell.height}px`;
366
402
  element.style.top = `${row * this.dimensions.css.cell.height}px`;
367
- element.style.left = `${colStart * this.dimensions.css.cell.width}px`;
368
- element.style.width = `${this.dimensions.css.cell.width * (colEnd - colStart)}px`;
403
+ element.style.left = `${left}px`;
404
+ element.style.width = `${width}px`;
369
405
  return element;
370
406
  }
371
407
 
@@ -406,8 +442,8 @@ export class DomRenderer extends Disposable implements IRenderer {
406
442
  const buffer = this._bufferService.buffer;
407
443
  const cursorAbsoluteY = buffer.ybase + buffer.y;
408
444
  const cursorX = Math.min(buffer.x, this._bufferService.cols - 1);
409
- const cursorBlink = this._optionsService.rawOptions.cursorBlink;
410
- const cursorStyle = this._optionsService.rawOptions.cursorStyle;
445
+ const cursorBlink = this._coreService.decPrivateModes.cursorBlink ?? this._optionsService.rawOptions.cursorBlink;
446
+ const cursorStyle = this._coreService.decPrivateModes.cursorStyle ?? this._optionsService.rawOptions.cursorStyle;
411
447
  const cursorInactiveStyle = this._optionsService.rawOptions.cursorInactiveStyle;
412
448
 
413
449
  for (let y = start; y <= end; y++) {