mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Fix other leaking listeners
This commit is contained in:
@@ -8,7 +8,8 @@ import { IDisposable } from 'common/Types';
|
||||
import { IMouseService, IRenderService } from './services/Services';
|
||||
import { IBufferService } from 'common/services/Services';
|
||||
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
import { Disposable, getDisposeArrayDisposable } from 'common/Lifecycle';
|
||||
import { addDisposableDomListener } from 'browser/Lifecycle';
|
||||
|
||||
interface ILinkState {
|
||||
decorations: ILinkDecorations;
|
||||
@@ -36,6 +37,7 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
||||
@IBufferService private readonly _bufferService: IBufferService
|
||||
) {
|
||||
super();
|
||||
this.register(getDisposeArrayDisposable(this._linkCacheDisposables));
|
||||
}
|
||||
|
||||
public registerLinkProvider(linkProvider: ILinkProvider): IDisposable {
|
||||
@@ -57,12 +59,12 @@ export class Linkifier2 extends Disposable implements ILinkifier2 {
|
||||
this._mouseService = mouseService;
|
||||
this._renderService = renderService;
|
||||
|
||||
this._element.addEventListener('mouseleave', () => {
|
||||
this.register(addDisposableDomListener(this._element, 'mouseleave', () => {
|
||||
this._isMouseOut = true;
|
||||
this._clearCurrentLink();
|
||||
});
|
||||
this._element.addEventListener('mousemove', this._onMouseMove.bind(this));
|
||||
this._element.addEventListener('click', this._onClick.bind(this));
|
||||
}));
|
||||
this.register(addDisposableDomListener(this._element, 'mousemove', this._onMouseMove.bind(this)));
|
||||
this.register(addDisposableDomListener(this._element, 'click', this._onClick.bind(this)));
|
||||
}
|
||||
|
||||
private _onMouseMove(event: MouseEvent): void {
|
||||
|
||||
@@ -417,7 +417,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
this._colorManager.setTheme(this._theme);
|
||||
|
||||
const renderer = this._createRenderer();
|
||||
this._renderService = this._instantiationService.createInstance(RenderService, renderer, this.rows, this.screenElement);
|
||||
this._renderService = this.register(this._instantiationService.createInstance(RenderService, renderer, this.rows, this.screenElement));
|
||||
this._instantiationService.setService(IRenderService, this._renderService);
|
||||
this.register(this._renderService.onRenderedBufferChange(e => this._onRender.fire(e)));
|
||||
this.onResize(e => this._renderService!.resize(e.cols, e.rows));
|
||||
|
||||
@@ -60,7 +60,7 @@ export abstract class BaseRenderLayer implements IRenderLayer {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._container.removeChild(this._canvas);
|
||||
this._canvas.parentElement?.removeChild(this._canvas);
|
||||
this._charAtlas?.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -71,8 +71,8 @@ export class Renderer extends Disposable implements IRenderer {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
this._renderLayers.forEach(l => l.dispose());
|
||||
super.dispose();
|
||||
removeTerminalFromCache(this._id);
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
screenElement: HTMLElement,
|
||||
@IOptionsService optionsService: IOptionsService,
|
||||
@ICharSizeService charSizeService: ICharSizeService,
|
||||
@IBufferService private readonly _bufferService: IBufferService
|
||||
@IBufferService bufferService: IBufferService
|
||||
) {
|
||||
super();
|
||||
this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end));
|
||||
@@ -62,7 +62,7 @@ export class RenderService extends Disposable implements IRenderService {
|
||||
this._screenDprMonitor.setListener(() => this.onDevicePixelRatioChange());
|
||||
this.register(this._screenDprMonitor);
|
||||
|
||||
this.register(this._bufferService.onResize(e => this._fullRefresh()));
|
||||
this.register(bufferService.onResize(e => this._fullRefresh()));
|
||||
this.register(optionsService.onOptionChange(() => this._renderer.onOptionsChanged()));
|
||||
this.register(charSizeService.onCharSizeChange(() => this.onCharSizeChanged()));
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ export abstract class CoreTerminal extends Disposable implements ICoreTerminal {
|
||||
this._instantiationService = new InstantiationService();
|
||||
this.optionsService = new OptionsService(options);
|
||||
this._instantiationService.setService(IOptionsService, this.optionsService);
|
||||
this._bufferService = this._instantiationService.createInstance(BufferService);
|
||||
this._bufferService = this.register(this._instantiationService.createInstance(BufferService));
|
||||
this._instantiationService.setService(IBufferService, this._bufferService);
|
||||
this._logService = this._instantiationService.createInstance(LogService);
|
||||
this._instantiationService.setService(ILogService, this._logService);
|
||||
|
||||
@@ -47,3 +47,18 @@ export abstract class Disposable implements IDisposable {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose of all disposables in an array and set its length to 0.
|
||||
*/
|
||||
export function disposeArray(disposables: IDisposable[]): void {
|
||||
disposables.forEach(d => d.dispose());
|
||||
disposables.length = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a disposable that will dispose of an array of disposables when disposed.
|
||||
*/
|
||||
export function getDisposeArrayDisposable(array: IDisposable[]): IDisposable {
|
||||
return { dispose: () => disposeArray(array) };
|
||||
}
|
||||
|
||||
@@ -8,18 +8,19 @@ import { IAttributeData } from 'common/Types';
|
||||
import { Buffer } from 'common/buffer/Buffer';
|
||||
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
||||
import { IOptionsService, IBufferService } from 'common/services/Services';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
|
||||
/**
|
||||
* The BufferSet represents the set of two buffers used by xterm terminals (normal and alt) and
|
||||
* provides also utilities for working with them.
|
||||
*/
|
||||
export class BufferSet implements IBufferSet {
|
||||
export class BufferSet extends Disposable implements IBufferSet {
|
||||
private _normal: Buffer;
|
||||
private _alt: Buffer;
|
||||
private _activeBuffer: Buffer;
|
||||
|
||||
|
||||
private _onBufferActivate = new EventEmitter<{activeBuffer: IBuffer, inactiveBuffer: IBuffer}>();
|
||||
private _onBufferActivate = this.register(new EventEmitter<{activeBuffer: IBuffer, inactiveBuffer: IBuffer}>());
|
||||
public get onBufferActivate(): IEvent<{activeBuffer: IBuffer, inactiveBuffer: IBuffer}> { return this._onBufferActivate.event; }
|
||||
|
||||
/**
|
||||
@@ -30,6 +31,8 @@ export class BufferSet implements IBufferSet {
|
||||
optionsService: IOptionsService,
|
||||
bufferService: IBufferService
|
||||
) {
|
||||
super();
|
||||
|
||||
this._normal = new Buffer(true, optionsService, bufferService);
|
||||
this._normal.fillViewportRows();
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -3,7 +3,7 @@
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { IAttributeData, ICircularList, IBufferLine, ICellData, IMarker, ICharset } from 'common/Types';
|
||||
import { IAttributeData, ICircularList, IBufferLine, ICellData, IMarker, ICharset, IDisposable } from 'common/Types';
|
||||
import { IEvent } from 'common/EventEmitter';
|
||||
|
||||
// BufferIndex denotes a position in the buffer: [rowIndex, colIndex]
|
||||
@@ -47,7 +47,7 @@ export interface IBuffer {
|
||||
addMarker(y: number): IMarker;
|
||||
}
|
||||
|
||||
export interface IBufferSet {
|
||||
export interface IBufferSet extends IDisposable {
|
||||
alt: IBuffer;
|
||||
normal: IBuffer;
|
||||
active: IBuffer;
|
||||
|
||||
@@ -7,11 +7,12 @@ import { IBufferService, IOptionsService } from 'common/services/Services';
|
||||
import { BufferSet } from 'common/buffer/BufferSet';
|
||||
import { IBufferSet, IBuffer } from 'common/buffer/Types';
|
||||
import { EventEmitter, IEvent } from 'common/EventEmitter';
|
||||
import { Disposable } from 'common/Lifecycle';
|
||||
|
||||
export const MINIMUM_COLS = 2; // Less than 2 can mess with wide chars
|
||||
export const MINIMUM_ROWS = 1;
|
||||
|
||||
export class BufferService implements IBufferService {
|
||||
export class BufferService extends Disposable implements IBufferService {
|
||||
public serviceBrand: any;
|
||||
|
||||
public cols: number;
|
||||
@@ -28,11 +29,17 @@ export class BufferService implements IBufferService {
|
||||
constructor(
|
||||
@IOptionsService private _optionsService: IOptionsService
|
||||
) {
|
||||
super();
|
||||
this.cols = Math.max(_optionsService.options.cols, MINIMUM_COLS);
|
||||
this.rows = Math.max(_optionsService.options.rows, MINIMUM_ROWS);
|
||||
this.buffers = new BufferSet(_optionsService, this);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
super.dispose();
|
||||
this.buffers.dispose();
|
||||
}
|
||||
|
||||
public resize(cols: number, rows: number): void {
|
||||
this.cols = cols;
|
||||
this.rows = rows;
|
||||
@@ -42,6 +49,7 @@ export class BufferService implements IBufferService {
|
||||
}
|
||||
|
||||
public reset(): void {
|
||||
this.buffers.dispose();
|
||||
this.buffers = new BufferSet(this._optionsService, this);
|
||||
this.isUserScrolling = false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user