@xterm/xterm 5.6.0-beta.6 → 5.6.0-beta.60

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 (118) hide show
  1. package/README.md +7 -3
  2. package/css/xterm.css +71 -4
  3. package/lib/xterm.js +1 -1
  4. package/lib/xterm.js.map +1 -1
  5. package/lib/xterm.mjs +53 -0
  6. package/lib/xterm.mjs.map +7 -0
  7. package/package.json +43 -33
  8. package/src/browser/AccessibilityManager.ts +53 -25
  9. package/src/browser/{Terminal.ts → CoreBrowserTerminal.ts} +132 -144
  10. package/src/browser/Linkifier.ts +15 -13
  11. package/src/browser/LocalizableStrings.ts +15 -4
  12. package/src/browser/{Types.d.ts → Types.ts} +67 -15
  13. package/src/browser/Viewport.ts +142 -370
  14. package/src/browser/decorations/BufferDecorationRenderer.ts +14 -9
  15. package/src/browser/decorations/OverviewRulerRenderer.ts +40 -44
  16. package/src/browser/public/Terminal.ts +25 -19
  17. package/src/browser/renderer/dom/DomRenderer.ts +14 -16
  18. package/src/browser/renderer/shared/CharAtlasUtils.ts +4 -0
  19. package/src/browser/renderer/shared/CustomGlyphs.ts +6 -0
  20. package/src/browser/renderer/shared/DevicePixelObserver.ts +1 -2
  21. package/src/browser/renderer/shared/TextureAtlas.ts +3 -3
  22. package/src/browser/renderer/shared/{Types.d.ts → Types.ts} +4 -4
  23. package/src/browser/services/CharSizeService.ts +6 -6
  24. package/src/browser/services/CoreBrowserService.ts +15 -15
  25. package/src/browser/services/LinkProviderService.ts +2 -2
  26. package/src/browser/services/RenderService.ts +20 -20
  27. package/src/browser/services/SelectionService.ts +8 -8
  28. package/src/browser/services/Services.ts +13 -13
  29. package/src/browser/services/ThemeService.ts +17 -56
  30. package/src/browser/shared/Constants.ts +8 -0
  31. package/src/common/CircularList.ts +5 -5
  32. package/src/common/CoreTerminal.ts +35 -41
  33. package/src/common/InputHandler.ts +34 -28
  34. package/src/common/{Types.d.ts → Types.ts} +11 -17
  35. package/src/common/buffer/Buffer.ts +5 -1
  36. package/src/common/buffer/BufferSet.ts +5 -5
  37. package/src/common/buffer/Marker.ts +4 -4
  38. package/src/common/buffer/{Types.d.ts → Types.ts} +2 -2
  39. package/src/common/input/WriteBuffer.ts +3 -3
  40. package/src/common/parser/EscapeSequenceParser.ts +4 -4
  41. package/src/common/public/BufferNamespaceApi.ts +3 -3
  42. package/src/common/services/BufferService.ts +7 -7
  43. package/src/common/services/CoreMouseService.ts +5 -3
  44. package/src/common/services/CoreService.ts +6 -6
  45. package/src/common/services/DecorationService.ts +8 -9
  46. package/src/common/services/LogService.ts +2 -2
  47. package/src/common/services/OptionsService.ts +5 -5
  48. package/src/common/services/Services.ts +24 -17
  49. package/src/common/services/UnicodeService.ts +2 -2
  50. package/src/vs/base/browser/browser.ts +141 -0
  51. package/src/vs/base/browser/canIUse.ts +49 -0
  52. package/src/vs/base/browser/dom.ts +2369 -0
  53. package/src/vs/base/browser/fastDomNode.ts +316 -0
  54. package/src/vs/base/browser/globalPointerMoveMonitor.ts +112 -0
  55. package/src/vs/base/browser/iframe.ts +135 -0
  56. package/src/vs/base/browser/keyboardEvent.ts +213 -0
  57. package/src/vs/base/browser/mouseEvent.ts +229 -0
  58. package/src/vs/base/browser/touch.ts +372 -0
  59. package/src/vs/base/browser/ui/scrollbar/abstractScrollbar.ts +303 -0
  60. package/src/vs/base/browser/ui/scrollbar/horizontalScrollbar.ts +114 -0
  61. package/src/vs/base/browser/ui/scrollbar/scrollableElement.ts +720 -0
  62. package/src/vs/base/browser/ui/scrollbar/scrollableElementOptions.ts +165 -0
  63. package/src/vs/base/browser/ui/scrollbar/scrollbarArrow.ts +114 -0
  64. package/src/vs/base/browser/ui/scrollbar/scrollbarState.ts +243 -0
  65. package/src/vs/base/browser/ui/scrollbar/scrollbarVisibilityController.ts +118 -0
  66. package/src/vs/base/browser/ui/scrollbar/verticalScrollbar.ts +116 -0
  67. package/src/vs/base/browser/ui/widget.ts +57 -0
  68. package/src/vs/base/browser/window.ts +14 -0
  69. package/src/vs/base/common/arrays.ts +887 -0
  70. package/src/vs/base/common/arraysFind.ts +202 -0
  71. package/src/vs/base/common/assert.ts +71 -0
  72. package/src/vs/base/common/async.ts +1992 -0
  73. package/src/vs/base/common/cancellation.ts +148 -0
  74. package/src/vs/base/common/charCode.ts +450 -0
  75. package/src/vs/base/common/collections.ts +140 -0
  76. package/src/vs/base/common/decorators.ts +130 -0
  77. package/src/vs/base/common/equals.ts +146 -0
  78. package/src/vs/base/common/errors.ts +303 -0
  79. package/src/vs/base/common/event.ts +1778 -0
  80. package/src/vs/base/common/functional.ts +32 -0
  81. package/src/vs/base/common/hash.ts +316 -0
  82. package/src/vs/base/common/iterator.ts +159 -0
  83. package/src/vs/base/common/keyCodes.ts +526 -0
  84. package/src/vs/base/common/keybindings.ts +284 -0
  85. package/src/vs/base/common/lazy.ts +47 -0
  86. package/src/vs/base/common/lifecycle.ts +801 -0
  87. package/src/vs/base/common/linkedList.ts +142 -0
  88. package/src/vs/base/common/map.ts +202 -0
  89. package/src/vs/base/common/numbers.ts +98 -0
  90. package/src/vs/base/common/observable.ts +76 -0
  91. package/src/vs/base/common/observableInternal/api.ts +31 -0
  92. package/src/vs/base/common/observableInternal/autorun.ts +281 -0
  93. package/src/vs/base/common/observableInternal/base.ts +489 -0
  94. package/src/vs/base/common/observableInternal/debugName.ts +145 -0
  95. package/src/vs/base/common/observableInternal/derived.ts +428 -0
  96. package/src/vs/base/common/observableInternal/lazyObservableValue.ts +146 -0
  97. package/src/vs/base/common/observableInternal/logging.ts +328 -0
  98. package/src/vs/base/common/observableInternal/promise.ts +209 -0
  99. package/src/vs/base/common/observableInternal/utils.ts +610 -0
  100. package/src/vs/base/common/platform.ts +281 -0
  101. package/src/vs/base/common/scrollable.ts +522 -0
  102. package/src/vs/base/common/sequence.ts +34 -0
  103. package/src/vs/base/common/stopwatch.ts +43 -0
  104. package/src/vs/base/common/strings.ts +557 -0
  105. package/src/vs/base/common/symbols.ts +9 -0
  106. package/src/vs/base/common/uint.ts +59 -0
  107. package/src/vs/patches/nls.ts +90 -0
  108. package/src/vs/typings/base-common.d.ts +20 -0
  109. package/src/vs/typings/require.d.ts +42 -0
  110. package/src/vs/typings/thenable.d.ts +12 -0
  111. package/src/vs/typings/vscode-globals-nls.d.ts +36 -0
  112. package/src/vs/typings/vscode-globals-product.d.ts +33 -0
  113. package/typings/xterm.d.ts +59 -15
  114. package/src/browser/Lifecycle.ts +0 -33
  115. package/src/common/EventEmitter.ts +0 -78
  116. package/src/common/Lifecycle.ts +0 -108
  117. /package/src/browser/selection/{Types.d.ts → Types.ts} +0 -0
  118. /package/src/common/parser/{Types.d.ts → Types.ts} +0 -0
@@ -21,12 +21,11 @@
21
21
  * http://linux.die.net/man/7/urxvt
22
22
  */
23
23
 
24
+ import { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker } from '@xterm/xterm';
24
25
  import { copyHandler, handlePasteEvent, moveTextAreaUnderMouseCursor, paste, rightClickHandler } from 'browser/Clipboard';
25
- import { addDisposableDomListener } from 'browser/Lifecycle';
26
- import { Linkifier } from './Linkifier';
27
26
  import * as Strings from 'browser/LocalizableStrings';
28
27
  import { OscLinkProvider } from 'browser/OscLinkProvider';
29
- import { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal, IViewport } from 'browser/Types';
28
+ import { CharacterJoinerHandler, CustomKeyEventHandler, CustomWheelEventHandler, IBrowser, IBufferRange, ICompositionHelper, ILinkifier2, ITerminal } from 'browser/Types';
30
29
  import { Viewport } from 'browser/Viewport';
31
30
  import { BufferDecorationRenderer } from 'browser/decorations/BufferDecorationRenderer';
32
31
  import { OverviewRulerRenderer } from 'browser/decorations/OverviewRulerRenderer';
@@ -36,6 +35,7 @@ import { IRenderer } from 'browser/renderer/shared/Types';
36
35
  import { CharSizeService } from 'browser/services/CharSizeService';
37
36
  import { CharacterJoinerService } from 'browser/services/CharacterJoinerService';
38
37
  import { CoreBrowserService } from 'browser/services/CoreBrowserService';
38
+ import { LinkProviderService } from 'browser/services/LinkProviderService';
39
39
  import { MouseService } from 'browser/services/MouseService';
40
40
  import { RenderService } from 'browser/services/RenderService';
41
41
  import { SelectionService } from 'browser/services/SelectionService';
@@ -43,10 +43,8 @@ import { ICharSizeService, ICharacterJoinerService, ICoreBrowserService, ILinkPr
43
43
  import { ThemeService } from 'browser/services/ThemeService';
44
44
  import { channels, color } from 'common/Color';
45
45
  import { CoreTerminal } from 'common/CoreTerminal';
46
- import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter';
47
- import { MutableDisposable, toDisposable } from 'common/Lifecycle';
48
46
  import * as Browser from 'common/Platform';
49
- import { ColorRequestType, CoreMouseAction, CoreMouseButton, CoreMouseEventType, IColorEvent, ITerminalOptions, KeyboardResultType, ScrollSource, SpecialColorIndex } from 'common/Types';
47
+ import { ColorRequestType, CoreMouseAction, CoreMouseButton, CoreMouseEventType, IColorEvent, ITerminalOptions, KeyboardResultType, SpecialColorIndex } from 'common/Types';
50
48
  import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
51
49
  import { IBuffer } from 'common/buffer/Types';
52
50
  import { C0, C1_ESCAPED } from 'common/data/EscapeSequences';
@@ -54,24 +52,26 @@ import { evaluateKeyboardEvent } from 'common/input/Keyboard';
54
52
  import { toRgbString } from 'common/input/XParseColor';
55
53
  import { DecorationService } from 'common/services/DecorationService';
56
54
  import { IDecorationService } from 'common/services/Services';
57
- import { IDecoration, IDecorationOptions, IDisposable, ILinkProvider, IMarker } from '@xterm/xterm';
58
55
  import { WindowsOptionsReportType } from '../common/InputHandler';
59
56
  import { AccessibilityManager } from './AccessibilityManager';
60
- import { LinkProviderService } from 'browser/services/LinkProviderService';
57
+ import { Linkifier } from './Linkifier';
58
+ import { Emitter, Event } from 'vs/base/common/event';
59
+ import { addDisposableListener } from 'vs/base/browser/dom';
60
+ import { MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
61
61
 
62
- export class Terminal extends CoreTerminal implements ITerminal {
62
+ export class CoreBrowserTerminal extends CoreTerminal implements ITerminal {
63
63
  public textarea: HTMLTextAreaElement | undefined;
64
64
  public element: HTMLElement | undefined;
65
65
  public screenElement: HTMLElement | undefined;
66
66
 
67
67
  private _document: Document | undefined;
68
- private _viewportScrollArea: HTMLElement | undefined;
69
68
  private _viewportElement: HTMLElement | undefined;
70
69
  private _helperContainer: HTMLElement | undefined;
71
70
  private _compositionView: HTMLElement | undefined;
72
71
 
73
72
  public linkifier: ILinkifier2 | undefined;
74
73
  private _overviewRulerRenderer: OverviewRulerRenderer | undefined;
74
+ private _viewport: Viewport | undefined;
75
75
 
76
76
  public browser: IBrowser = Browser as any;
77
77
 
@@ -118,33 +118,32 @@ export class Terminal extends CoreTerminal implements ITerminal {
118
118
  */
119
119
  private _unprocessedDeadKey: boolean = false;
120
120
 
121
- public viewport: IViewport | undefined;
122
121
  private _compositionHelper: ICompositionHelper | undefined;
123
- private _accessibilityManager: MutableDisposable<AccessibilityManager> = this.register(new MutableDisposable());
122
+ private _accessibilityManager: MutableDisposable<AccessibilityManager> = this._register(new MutableDisposable());
124
123
 
125
- private readonly _onCursorMove = this.register(new EventEmitter<void>());
124
+ private readonly _onCursorMove = this._register(new Emitter<void>());
126
125
  public readonly onCursorMove = this._onCursorMove.event;
127
- private readonly _onKey = this.register(new EventEmitter<{ key: string, domEvent: KeyboardEvent }>());
126
+ private readonly _onKey = this._register(new Emitter<{ key: string, domEvent: KeyboardEvent }>());
128
127
  public readonly onKey = this._onKey.event;
129
- private readonly _onRender = this.register(new EventEmitter<{ start: number, end: number }>());
128
+ private readonly _onRender = this._register(new Emitter<{ start: number, end: number }>());
130
129
  public readonly onRender = this._onRender.event;
131
- private readonly _onSelectionChange = this.register(new EventEmitter<void>());
130
+ private readonly _onSelectionChange = this._register(new Emitter<void>());
132
131
  public readonly onSelectionChange = this._onSelectionChange.event;
133
- private readonly _onTitleChange = this.register(new EventEmitter<string>());
132
+ private readonly _onTitleChange = this._register(new Emitter<string>());
134
133
  public readonly onTitleChange = this._onTitleChange.event;
135
- private readonly _onBell = this.register(new EventEmitter<void>());
134
+ private readonly _onBell = this._register(new Emitter<void>());
136
135
  public readonly onBell = this._onBell.event;
137
136
 
138
- private _onFocus = this.register(new EventEmitter<void>());
139
- public get onFocus(): IEvent<void> { return this._onFocus.event; }
140
- private _onBlur = this.register(new EventEmitter<void>());
141
- public get onBlur(): IEvent<void> { return this._onBlur.event; }
142
- private _onA11yCharEmitter = this.register(new EventEmitter<string>());
143
- public get onA11yChar(): IEvent<string> { return this._onA11yCharEmitter.event; }
144
- private _onA11yTabEmitter = this.register(new EventEmitter<number>());
145
- public get onA11yTab(): IEvent<number> { return this._onA11yTabEmitter.event; }
146
- private _onWillOpen = this.register(new EventEmitter<HTMLElement>());
147
- public get onWillOpen(): IEvent<HTMLElement> { return this._onWillOpen.event; }
137
+ private _onFocus = this._register(new Emitter<void>());
138
+ public get onFocus(): Event<void> { return this._onFocus.event; }
139
+ private _onBlur = this._register(new Emitter<void>());
140
+ public get onBlur(): Event<void> { return this._onBlur.event; }
141
+ private _onA11yCharEmitter = this._register(new Emitter<string>());
142
+ public get onA11yChar(): Event<string> { return this._onA11yCharEmitter.event; }
143
+ private _onA11yTabEmitter = this._register(new Emitter<number>());
144
+ public get onA11yTab(): Event<number> { return this._onA11yTabEmitter.event; }
145
+ private _onWillOpen = this._register(new Emitter<HTMLElement>());
146
+ public get onWillOpen(): Event<HTMLElement> { return this._onWillOpen.event; }
148
147
 
149
148
  constructor(
150
149
  options: Partial<ITerminalOptions> = {}
@@ -160,21 +159,21 @@ export class Terminal extends CoreTerminal implements ITerminal {
160
159
  this._linkProviderService.registerLinkProvider(this._instantiationService.createInstance(OscLinkProvider));
161
160
 
162
161
  // Setup InputHandler listeners
163
- this.register(this._inputHandler.onRequestBell(() => this._onBell.fire()));
164
- this.register(this._inputHandler.onRequestRefreshRows((start, end) => this.refresh(start, end)));
165
- this.register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));
166
- this.register(this._inputHandler.onRequestReset(() => this.reset()));
167
- this.register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));
168
- this.register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));
169
- this.register(forwardEvent(this._inputHandler.onCursorMove, this._onCursorMove));
170
- this.register(forwardEvent(this._inputHandler.onTitleChange, this._onTitleChange));
171
- this.register(forwardEvent(this._inputHandler.onA11yChar, this._onA11yCharEmitter));
172
- this.register(forwardEvent(this._inputHandler.onA11yTab, this._onA11yTabEmitter));
162
+ this._register(this._inputHandler.onRequestBell(() => this._onBell.fire()));
163
+ this._register(this._inputHandler.onRequestRefreshRows((e) => this.refresh(e?.start ?? 0, e?.end ?? (this.rows - 1))));
164
+ this._register(this._inputHandler.onRequestSendFocus(() => this._reportFocus()));
165
+ this._register(this._inputHandler.onRequestReset(() => this.reset()));
166
+ this._register(this._inputHandler.onRequestWindowsOptionsReport(type => this._reportWindowsOptions(type)));
167
+ this._register(this._inputHandler.onColor((event) => this._handleColorEvent(event)));
168
+ this._register(Event.forward(this._inputHandler.onCursorMove, this._onCursorMove));
169
+ this._register(Event.forward(this._inputHandler.onTitleChange, this._onTitleChange));
170
+ this._register(Event.forward(this._inputHandler.onA11yChar, this._onA11yCharEmitter));
171
+ this._register(Event.forward(this._inputHandler.onA11yTab, this._onA11yTabEmitter));
173
172
 
174
173
  // Setup listeners
175
- this.register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));
174
+ this._register(this._bufferService.onResize(e => this._afterResize(e.cols, e.rows)));
176
175
 
177
- this.register(toDisposable(() => {
176
+ this._register(toDisposable(() => {
178
177
  this._customKeyEventHandler = undefined;
179
178
  this.element?.parentNode?.removeChild(this.element);
180
179
  }));
@@ -331,7 +330,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
331
330
  this._bindKeys();
332
331
 
333
332
  // Bind clipboard functionality
334
- this.register(addDisposableDomListener(this.element!, 'copy', (event: ClipboardEvent) => {
333
+ this._register(addDisposableListener(this.element!, 'copy', (event: ClipboardEvent) => {
335
334
  // If mouse events are active it means the selection manager is disabled and
336
335
  // copy should be handled by the host program.
337
336
  if (!this.hasSelection()) {
@@ -340,19 +339,19 @@ export class Terminal extends CoreTerminal implements ITerminal {
340
339
  copyHandler(event, this._selectionService!);
341
340
  }));
342
341
  const pasteHandlerWrapper = (event: ClipboardEvent): void => handlePasteEvent(event, this.textarea!, this.coreService, this.optionsService);
343
- this.register(addDisposableDomListener(this.textarea!, 'paste', pasteHandlerWrapper));
344
- this.register(addDisposableDomListener(this.element!, 'paste', pasteHandlerWrapper));
342
+ this._register(addDisposableListener(this.textarea!, 'paste', pasteHandlerWrapper));
343
+ this._register(addDisposableListener(this.element!, 'paste', pasteHandlerWrapper));
345
344
 
346
345
  // Handle right click context menus
347
346
  if (Browser.isFirefox) {
348
347
  // Firefox doesn't appear to fire the contextmenu event on right click
349
- this.register(addDisposableDomListener(this.element!, 'mousedown', (event: MouseEvent) => {
348
+ this._register(addDisposableListener(this.element!, 'mousedown', (event: MouseEvent) => {
350
349
  if (event.button === 2) {
351
350
  rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);
352
351
  }
353
352
  }));
354
353
  } else {
355
- this.register(addDisposableDomListener(this.element!, 'contextmenu', (event: MouseEvent) => {
354
+ this._register(addDisposableListener(this.element!, 'contextmenu', (event: MouseEvent) => {
356
355
  rightClickHandler(event, this.textarea!, this.screenElement!, this._selectionService!, this.options.rightClickSelectsWord);
357
356
  }));
358
357
  }
@@ -363,7 +362,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
363
362
  if (Browser.isLinux) {
364
363
  // Use auxclick event over mousedown the latter doesn't seem to work. Note
365
364
  // that the regular click event doesn't fire for the middle mouse button.
366
- this.register(addDisposableDomListener(this.element!, 'auxclick', (event: MouseEvent) => {
365
+ this._register(addDisposableListener(this.element!, 'auxclick', (event: MouseEvent) => {
367
366
  if (event.button === 1) {
368
367
  moveTextAreaUnderMouseCursor(event, this.textarea!, this.screenElement!);
369
368
  }
@@ -375,14 +374,14 @@ export class Terminal extends CoreTerminal implements ITerminal {
375
374
  * Apply key handling to the terminal
376
375
  */
377
376
  private _bindKeys(): void {
378
- this.register(addDisposableDomListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));
379
- this.register(addDisposableDomListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));
380
- this.register(addDisposableDomListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));
381
- this.register(addDisposableDomListener(this.textarea!, 'compositionstart', () => this._compositionHelper!.compositionstart()));
382
- this.register(addDisposableDomListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));
383
- this.register(addDisposableDomListener(this.textarea!, 'compositionend', () => this._compositionHelper!.compositionend()));
384
- this.register(addDisposableDomListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));
385
- this.register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));
377
+ this._register(addDisposableListener(this.textarea!, 'keyup', (ev: KeyboardEvent) => this._keyUp(ev), true));
378
+ this._register(addDisposableListener(this.textarea!, 'keydown', (ev: KeyboardEvent) => this._keyDown(ev), true));
379
+ this._register(addDisposableListener(this.textarea!, 'keypress', (ev: KeyboardEvent) => this._keyPress(ev), true));
380
+ this._register(addDisposableListener(this.textarea!, 'compositionstart', () => this._compositionHelper!.compositionstart()));
381
+ this._register(addDisposableListener(this.textarea!, 'compositionupdate', (e: CompositionEvent) => this._compositionHelper!.compositionupdate(e)));
382
+ this._register(addDisposableListener(this.textarea!, 'compositionend', () => this._compositionHelper!.compositionend()));
383
+ this._register(addDisposableListener(this.textarea!, 'input', (ev: InputEvent) => this._inputEvent(ev), true));
384
+ this._register(this.onRender(() => this._compositionHelper!.updateCompositionElements()));
386
385
  }
387
386
 
388
387
  /**
@@ -427,13 +426,9 @@ export class Terminal extends CoreTerminal implements ITerminal {
427
426
  this._viewportElement.classList.add('xterm-viewport');
428
427
  fragment.appendChild(this._viewportElement);
429
428
 
430
- this._viewportScrollArea = this._document.createElement('div');
431
- this._viewportScrollArea.classList.add('xterm-scroll-area');
432
- this._viewportElement.appendChild(this._viewportScrollArea);
433
-
434
429
  this.screenElement = this._document.createElement('div');
435
430
  this.screenElement.classList.add('xterm-screen');
436
- this.register(addDisposableDomListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));
431
+ this._register(addDisposableListener(this.screenElement, 'mousemove', (ev: MouseEvent) => this.updateCursorStyle(ev)));
437
432
  // Create the container that will hold helpers like the textarea for
438
433
  // capturing DOM Events. Then produce the helpers.
439
434
  this._helperContainer = this._document.createElement('div');
@@ -443,7 +438,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
443
438
 
444
439
  this.textarea = this._document.createElement('textarea');
445
440
  this.textarea.classList.add('xterm-helper-textarea');
446
- this.textarea.setAttribute('aria-label', Strings.promptLabel);
441
+ this.textarea.setAttribute('aria-label', Strings.promptLabel.get());
447
442
  if (!Browser.isChromeOS) {
448
443
  // ChromeVox on ChromeOS does not like this. See
449
444
  // https://issuetracker.google.com/issues/260170397
@@ -456,7 +451,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
456
451
 
457
452
  // Register the core browser service before the generic textarea handlers are registered so it
458
453
  // handles them first. Otherwise the renderers may use the wrong focus state.
459
- this._coreBrowserService = this.register(this._instantiationService.createInstance(CoreBrowserService,
454
+ this._coreBrowserService = this._register(this._instantiationService.createInstance(CoreBrowserService,
460
455
  this.textarea,
461
456
  parent.ownerDocument.defaultView ?? window,
462
457
  // Force unsafe null in node.js environment for tests
@@ -464,8 +459,8 @@ export class Terminal extends CoreTerminal implements ITerminal {
464
459
  ));
465
460
  this._instantiationService.setService(ICoreBrowserService, this._coreBrowserService);
466
461
 
467
- this.register(addDisposableDomListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));
468
- this.register(addDisposableDomListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));
462
+ this._register(addDisposableListener(this.textarea, 'focus', (ev: FocusEvent) => this._handleTextAreaFocus(ev)));
463
+ this._register(addDisposableListener(this.textarea, 'blur', () => this._handleTextAreaBlur()));
469
464
  this._helperContainer.appendChild(this.textarea);
470
465
 
471
466
  this._charSizeService = this._instantiationService.createInstance(CharSizeService, this._document, this._helperContainer);
@@ -477,9 +472,9 @@ export class Terminal extends CoreTerminal implements ITerminal {
477
472
  this._characterJoinerService = this._instantiationService.createInstance(CharacterJoinerService);
478
473
  this._instantiationService.setService(ICharacterJoinerService, this._characterJoinerService);
479
474
 
480
- this._renderService = this.register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));
475
+ this._renderService = this._register(this._instantiationService.createInstance(RenderService, this.rows, this.screenElement));
481
476
  this._instantiationService.setService(IRenderService, this._renderService);
482
- this.register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));
477
+ this._register(this._renderService.onRenderedViewportChange(e => this._onRender.fire(e)));
483
478
  this.onResize(e => this._renderService!.resize(e.cols, e.rows));
484
479
 
485
480
  this._compositionView = this._document.createElement('div');
@@ -490,7 +485,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
490
485
  this._mouseService = this._instantiationService.createInstance(MouseService);
491
486
  this._instantiationService.setService(IMouseService, this._mouseService);
492
487
 
493
- this.linkifier = this.register(this._instantiationService.createInstance(Linkifier, this.screenElement));
488
+ this.linkifier = this._register(this._instantiationService.createInstance(Linkifier, this.screenElement));
494
489
 
495
490
  // Performance: Add viewport and helper elements from the fragment
496
491
  this.element.appendChild(fragment);
@@ -503,30 +498,30 @@ export class Terminal extends CoreTerminal implements ITerminal {
503
498
  this._renderService.setRenderer(this._createRenderer());
504
499
  }
505
500
 
506
- this.viewport = this._instantiationService.createInstance(Viewport, this._viewportElement, this._viewportScrollArea);
507
- this.viewport.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent, ScrollSource.VIEWPORT)),
508
- this.register(this._inputHandler.onRequestSyncScrollBar(() => this.viewport!.syncScrollArea()));
509
- this.register(this.viewport);
510
-
511
- this.register(this.onCursorMove(() => {
501
+ this._register(this.onCursorMove(() => {
512
502
  this._renderService!.handleCursorMove();
513
503
  this._syncTextArea();
514
504
  }));
515
- this.register(this.onResize(() => this._renderService!.handleResize(this.cols, this.rows)));
516
- this.register(this.onBlur(() => this._renderService!.handleBlur()));
517
- this.register(this.onFocus(() => this._renderService!.handleFocus()));
518
- this.register(this._renderService.onDimensionsChange(() => this.viewport!.syncScrollArea()));
505
+ this._register(this.onResize(() => this._renderService!.handleResize(this.cols, this.rows)));
506
+ this._register(this.onBlur(() => this._renderService!.handleBlur()));
507
+ this._register(this.onFocus(() => this._renderService!.handleFocus()));
508
+
509
+ this._viewport = this._register(this._instantiationService.createInstance(Viewport, this.element, this.screenElement));
510
+ this._register(this._viewport.onRequestScrollLines(e => {
511
+ super.scrollLines(e, false);
512
+ this.refresh(0, this.rows - 1);
513
+ }));
519
514
 
520
- this._selectionService = this.register(this._instantiationService.createInstance(SelectionService,
515
+ this._selectionService = this._register(this._instantiationService.createInstance(SelectionService,
521
516
  this.element,
522
517
  this.screenElement,
523
518
  this.linkifier
524
519
  ));
525
520
  this._instantiationService.setService(ISelectionService, this._selectionService);
526
- this.register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));
527
- this.register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));
528
- this.register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));
529
- this.register(this._selectionService.onLinuxMouseSelection(text => {
521
+ this._register(this._selectionService.onRequestScrollLines(e => this.scrollLines(e.amount, e.suppressScrollEvent)));
522
+ this._register(this._selectionService.onSelectionChange(() => this._onSelectionChange.fire()));
523
+ this._register(this._selectionService.onRequestRedraw(e => this._renderService!.handleSelectionChanged(e.start, e.end, e.columnSelectMode)));
524
+ this._register(this._selectionService.onLinuxMouseSelection(text => {
530
525
  // If there's a new selection, put it into the textarea, focus and select it
531
526
  // in order to register it as a selection on the OS. This event is fired
532
527
  // only on Linux to enable middle click to paste selection.
@@ -534,14 +529,10 @@ export class Terminal extends CoreTerminal implements ITerminal {
534
529
  this.textarea!.focus();
535
530
  this.textarea!.select();
536
531
  }));
537
- this.register(this._onScroll.event(ev => {
538
- this.viewport!.syncScrollArea();
539
- this._selectionService!.refresh();
540
- }));
541
- this.register(addDisposableDomListener(this._viewportElement, 'scroll', () => this._selectionService!.refresh()));
532
+ this._register(this._onScroll.event(() => this._selectionService!.refresh()));
542
533
 
543
- this.register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));
544
- this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));
534
+ this._register(this._instantiationService.createInstance(BufferDecorationRenderer, this.screenElement));
535
+ this._register(addDisposableListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.handleMouseDown(e)));
545
536
 
546
537
  // apply mouse event classes set by escape codes before terminal was attached
547
538
  if (this.coreMouseService.areMouseEventsActive) {
@@ -556,14 +547,14 @@ export class Terminal extends CoreTerminal implements ITerminal {
556
547
  // ensure the correct order of the dprchange event
557
548
  this._accessibilityManager.value = this._instantiationService.createInstance(AccessibilityManager, this);
558
549
  }
559
- this.register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));
550
+ this._register(this.optionsService.onSpecificOptionChange('screenReaderMode', e => this._handleScreenReaderModeOptionChange(e)));
560
551
 
561
- if (this.options.overviewRulerWidth) {
562
- this._overviewRulerRenderer = this.register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));
552
+ if (this.options.overviewRuler.width) {
553
+ this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));
563
554
  }
564
- this.optionsService.onSpecificOptionChange('overviewRulerWidth', value => {
555
+ this.optionsService.onSpecificOptionChange('overviewRuler', value => {
565
556
  if (!this._overviewRulerRenderer && value && this._viewportElement && this.screenElement) {
566
- this._overviewRulerRenderer = this.register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));
557
+ this._overviewRulerRenderer = this._register(this._instantiationService.createInstance(OverviewRulerRenderer, this._viewportElement, this.screenElement));
567
558
  }
568
559
  });
569
560
  // Measure the character size
@@ -642,13 +633,11 @@ export class Terminal extends CoreTerminal implements ITerminal {
642
633
  if (self._customWheelEventHandler && self._customWheelEventHandler(ev as WheelEvent) === false) {
643
634
  return false;
644
635
  }
645
- const amount = self.viewport!.getLinesScrolled(ev as WheelEvent);
646
-
647
- if (amount === 0) {
636
+ const deltaY = (ev as WheelEvent).deltaY;
637
+ if (deltaY === 0) {
648
638
  return false;
649
639
  }
650
-
651
- action = (ev as WheelEvent).deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;
640
+ action = deltaY < 0 ? CoreMouseAction.UP : CoreMouseAction.DOWN;
652
641
  but = CoreMouseButton.WHEEL;
653
642
  break;
654
643
  default:
@@ -683,7 +672,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
683
672
  * Note: 'mousedown' currently is "always on" and not managed
684
673
  * by onProtocolChange.
685
674
  */
686
- const requestedEvents: { [key: string]: ((ev: Event) => void) | null } = {
675
+ const requestedEvents: { [key: string]: ((ev: MouseEvent | WheelEvent) => void) | null } = {
687
676
  mouseup: null,
688
677
  wheel: null,
689
678
  mousedrag: null,
@@ -718,7 +707,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
718
707
  }
719
708
  }
720
709
  };
721
- this.register(this.coreMouseService.onProtocolChange(events => {
710
+ this._register(this.coreMouseService.onProtocolChange(events => {
722
711
  // apply global changes on events
723
712
  if (events) {
724
713
  if (this.optionsService.rawOptions.logLevel === 'debug') {
@@ -770,7 +759,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
770
759
  /**
771
760
  * "Always on" event listeners.
772
761
  */
773
- this.register(addDisposableDomListener(el, 'mousedown', (ev: MouseEvent) => {
762
+ this._register(addDisposableListener(el, 'mousedown', (ev: MouseEvent) => {
774
763
  ev.preventDefault();
775
764
  this.focus();
776
765
 
@@ -797,7 +786,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
797
786
  return this.cancel(ev);
798
787
  }));
799
788
 
800
- this.register(addDisposableDomListener(el, 'wheel', (ev: WheelEvent) => {
789
+ this._register(addDisposableListener(el, 'wheel', (ev: WheelEvent) => {
801
790
  // do nothing, if app side handles wheel itself
802
791
  if (requestedEvents.wheel) return;
803
792
 
@@ -807,42 +796,23 @@ export class Terminal extends CoreTerminal implements ITerminal {
807
796
 
808
797
  if (!this.buffer.hasScrollback) {
809
798
  // Convert wheel events into up/down events when the buffer does not have scrollback, this
810
- // enables scrolling in apps hosted in the alt buffer such as vim or tmux.
811
- const amount = this.viewport!.getLinesScrolled(ev);
799
+ // enables scrolling in apps hosted in the alt buffer such as vim or tmux even when mouse
800
+ // events are not enabled.
801
+ // This used implementation used get the actual lines/partial lines scrolled from the
802
+ // viewport but since moving to the new viewport implementation has been simplified to
803
+ // simply send a single up or down sequence.
812
804
 
813
805
  // Do nothing if there's no vertical scroll
814
- if (amount === 0) {
815
- return;
806
+ const deltaY = (ev as WheelEvent).deltaY;
807
+ if (deltaY === 0) {
808
+ return false;
816
809
  }
817
810
 
818
811
  // Construct and send sequences
819
812
  const sequence = C0.ESC + (this.coreService.decPrivateModes.applicationCursorKeys ? 'O' : '[') + (ev.deltaY < 0 ? 'A' : 'B');
820
- let data = '';
821
- for (let i = 0; i < Math.abs(amount); i++) {
822
- data += sequence;
823
- }
824
- this.coreService.triggerDataEvent(data, true);
813
+ this.coreService.triggerDataEvent(sequence, true);
825
814
  return this.cancel(ev, true);
826
815
  }
827
-
828
- // normal viewport scrolling
829
- // conditionally stop event, if the viewport still had rows to scroll within
830
- if (this.viewport!.handleWheel(ev)) {
831
- return this.cancel(ev);
832
- }
833
- }, { passive: false }));
834
-
835
- this.register(addDisposableDomListener(el, 'touchstart', (ev: TouchEvent) => {
836
- if (this.coreMouseService.areMouseEventsActive) return;
837
- this.viewport!.handleTouchStart(ev);
838
- return this.cancel(ev);
839
- }, { passive: true }));
840
-
841
- this.register(addDisposableDomListener(el, 'touchmove', (ev: TouchEvent) => {
842
- if (this.coreMouseService.areMouseEventsActive) return;
843
- if (!this.viewport!.handleTouchMove(ev)) {
844
- return this.cancel(ev);
845
- }
846
816
  }, { passive: false }));
847
817
  }
848
818
 
@@ -878,12 +848,36 @@ export class Terminal extends CoreTerminal implements ITerminal {
878
848
  }
879
849
  }
880
850
 
881
- public scrollLines(disp: number, suppressScrollEvent?: boolean, source = ScrollSource.TERMINAL): void {
882
- if (source === ScrollSource.VIEWPORT) {
883
- super.scrollLines(disp, suppressScrollEvent, source);
884
- this.refresh(0, this.rows - 1);
851
+ public scrollLines(disp: number, suppressScrollEvent?: boolean): void {
852
+ // All scrollLines methods need to go via the viewport in order to support smooth scroll
853
+ if (this._viewport) {
854
+ this._viewport.scrollLines(disp);
885
855
  } else {
886
- this.viewport?.scrollLines(disp);
856
+ super.scrollLines(disp, suppressScrollEvent);
857
+ }
858
+ this.refresh(0, this.rows - 1);
859
+ }
860
+
861
+ public scrollPages(pageCount: number): void {
862
+ this.scrollLines(pageCount * (this.rows - 1));
863
+ }
864
+
865
+ public scrollToTop(): void {
866
+ this.scrollLines(-this._bufferService.buffer.ydisp);
867
+ }
868
+
869
+ public scrollToBottom(disableSmoothScroll?: boolean): void {
870
+ if (disableSmoothScroll && this._viewport) {
871
+ this._viewport.scrollToLine(this.buffer.ybase, true);
872
+ } else {
873
+ this.scrollLines(this._bufferService.buffer.ybase - this._bufferService.buffer.ydisp);
874
+ }
875
+ }
876
+
877
+ public scrollToLine(line: number): void {
878
+ const scrollAmount = line - this._bufferService.buffer.ydisp;
879
+ if (scrollAmount !== 0) {
880
+ this.scrollLines(scrollAmount);
887
881
  }
888
882
  }
889
883
 
@@ -1011,7 +1005,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
1011
1005
 
1012
1006
  if (!shouldIgnoreComposition && !this._compositionHelper!.keydown(event)) {
1013
1007
  if (this.options.scrollOnUserInput && this.buffer.ybase !== this.buffer.ydisp) {
1014
- this.scrollToBottom();
1008
+ this.scrollToBottom(true);
1015
1009
  }
1016
1010
  return false;
1017
1011
  }
@@ -1212,10 +1206,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
1212
1206
 
1213
1207
  private _afterResize(x: number, y: number): void {
1214
1208
  this._charSizeService?.measure();
1215
-
1216
- // Sync the scroll area to make sure scroll events don't fire and scroll the viewport to an
1217
- // invalid location
1218
- this.viewport?.syncScrollArea(true);
1219
1209
  }
1220
1210
 
1221
1211
  /**
@@ -1237,8 +1227,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
1237
1227
  }
1238
1228
  // IMPORTANT: Fire scroll event before viewport is reset. This ensures embedders get the clear
1239
1229
  // scroll event and that the viewport's state will be valid for immediate writes.
1240
- this._onScroll.fire({ position: this.buffer.ydisp, source: ScrollSource.TERMINAL });
1241
- this.viewport?.reset();
1230
+ this._onScroll.fire({ position: this.buffer.ydisp });
1242
1231
  this.refresh(0, this.rows - 1);
1243
1232
  }
1244
1233
 
@@ -1263,7 +1252,6 @@ export class Terminal extends CoreTerminal implements ITerminal {
1263
1252
  super.reset();
1264
1253
  this._selectionService?.reset();
1265
1254
  this._decorationService.reset();
1266
- this.viewport?.reset();
1267
1255
 
1268
1256
  // reattach
1269
1257
  this._customKeyEventHandler = customKeyEventHandler;
@@ -1304,7 +1292,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
1304
1292
  }
1305
1293
 
1306
1294
  // TODO: Remove cancel function and cancelEvents option
1307
- public cancel(ev: Event, force?: boolean): boolean | undefined {
1295
+ public cancel(ev: MouseEvent | WheelEvent | KeyboardEvent | InputEvent, force?: boolean): boolean | undefined {
1308
1296
  if (!this.options.cancelEvents && !force) {
1309
1297
  return;
1310
1298
  }
@@ -3,13 +3,13 @@
3
3
  * @license MIT
4
4
  */
5
5
 
6
- import { addDisposableDomListener } from 'browser/Lifecycle';
7
6
  import { IBufferCellPosition, ILink, ILinkDecorations, ILinkWithState, ILinkifier2, ILinkifierEvent } from 'browser/Types';
8
- import { EventEmitter } from 'common/EventEmitter';
9
- import { Disposable, disposeArray, getDisposeArrayDisposable, toDisposable } from 'common/Lifecycle';
7
+ import { Disposable, dispose, toDisposable } from 'vs/base/common/lifecycle';
10
8
  import { IDisposable } from 'common/Types';
11
9
  import { IBufferService } from 'common/services/Services';
12
10
  import { ILinkProviderService, IMouseService, IRenderService } from './services/Services';
11
+ import { Emitter } from 'vs/base/common/event';
12
+ import { addDisposableListener } from 'vs/base/browser/dom';
13
13
 
14
14
  export class Linkifier extends Disposable implements ILinkifier2 {
15
15
  public get currentLink(): ILinkWithState | undefined { return this._currentLink; }
@@ -23,9 +23,9 @@ export class Linkifier extends Disposable implements ILinkifier2 {
23
23
  private _activeProviderReplies: Map<Number, ILinkWithState[] | undefined> | undefined;
24
24
  private _activeLine: number = -1;
25
25
 
26
- private readonly _onShowLinkUnderline = this.register(new EventEmitter<ILinkifierEvent>());
26
+ private readonly _onShowLinkUnderline = this._register(new Emitter<ILinkifierEvent>());
27
27
  public readonly onShowLinkUnderline = this._onShowLinkUnderline.event;
28
- private readonly _onHideLinkUnderline = this.register(new EventEmitter<ILinkifierEvent>());
28
+ private readonly _onHideLinkUnderline = this._register(new Emitter<ILinkifierEvent>());
29
29
  public readonly onHideLinkUnderline = this._onHideLinkUnderline.event;
30
30
 
31
31
  constructor(
@@ -36,24 +36,25 @@ export class Linkifier extends Disposable implements ILinkifier2 {
36
36
  @ILinkProviderService private readonly _linkProviderService: ILinkProviderService
37
37
  ) {
38
38
  super();
39
- this.register(getDisposeArrayDisposable(this._linkCacheDisposables));
40
- this.register(toDisposable(() => {
39
+ this._register(toDisposable(() => {
40
+ dispose(this._linkCacheDisposables);
41
+ this._linkCacheDisposables.length = 0;
41
42
  this._lastMouseEvent = undefined;
42
43
  // Clear out link providers as they could easily cause an embedder memory leak
43
44
  this._activeProviderReplies?.clear();
44
45
  }));
45
46
  // Listen to resize to catch the case where it's resized and the cursor is out of the viewport.
46
- this.register(this._bufferService.onResize(() => {
47
+ this._register(this._bufferService.onResize(() => {
47
48
  this._clearCurrentLink();
48
49
  this._wasResized = true;
49
50
  }));
50
- this.register(addDisposableDomListener(this._element, 'mouseleave', () => {
51
+ this._register(addDisposableListener(this._element, 'mouseleave', () => {
51
52
  this._isMouseOut = true;
52
53
  this._clearCurrentLink();
53
54
  }));
54
- this.register(addDisposableDomListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));
55
- this.register(addDisposableDomListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));
56
- this.register(addDisposableDomListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));
55
+ this._register(addDisposableListener(this._element, 'mousemove', this._handleMouseMove.bind(this)));
56
+ this._register(addDisposableListener(this._element, 'mousedown', this._handleMouseDown.bind(this)));
57
+ this._register(addDisposableListener(this._element, 'mouseup', this._handleMouseUp.bind(this)));
57
58
  }
58
59
 
59
60
  private _handleMouseMove(event: MouseEvent): void {
@@ -240,7 +241,8 @@ export class Linkifier extends Disposable implements ILinkifier2 {
240
241
  if (!startRow || !endRow || (this._currentLink.link.range.start.y >= startRow && this._currentLink.link.range.end.y <= endRow)) {
241
242
  this._linkLeave(this._element, this._currentLink.link, this._lastMouseEvent);
242
243
  this._currentLink = undefined;
243
- disposeArray(this._linkCacheDisposables);
244
+ dispose(this._linkCacheDisposables);
245
+ this._linkCacheDisposables.length = 0;
244
246
  }
245
247
  }
246
248