72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
/**
|
|
* Copyright (c) 2014, 2019 The xterm.js authors. All rights reserved.
|
|
* @license MIT
|
|
*
|
|
* Implements the attach method, that attaches the terminal to a WebSocket stream.
|
|
*/
|
|
|
|
import { Terminal, IDisposable, ITerminalAddon } from 'xterm';
|
|
|
|
interface IAttachOptions {
|
|
bidirectional?: boolean;
|
|
inputUtf8?: boolean;
|
|
}
|
|
|
|
export class AttachAddon implements ITerminalAddon {
|
|
private _socket: WebSocket;
|
|
private _bidirectional: boolean;
|
|
private _utf8: boolean;
|
|
private _disposables: IDisposable[] = [];
|
|
|
|
constructor(socket: WebSocket, options?: IAttachOptions) {
|
|
this._socket = socket;
|
|
// always set binary type to arraybuffer, we do not handle blobs
|
|
this._socket.binaryType = 'arraybuffer';
|
|
this._bidirectional = (options && options.bidirectional === false) ? false : true;
|
|
this._utf8 = !!(options && options.inputUtf8);
|
|
}
|
|
|
|
public activate(terminal: Terminal): void {
|
|
if (this._utf8) {
|
|
this._disposables.push(addSocketListener(this._socket, 'message',
|
|
(ev: MessageEvent | Event | CloseEvent) => terminal.writeUtf8(new Uint8Array((ev as any).data as ArrayBuffer))));
|
|
} else {
|
|
this._disposables.push(addSocketListener(this._socket, 'message',
|
|
(ev: MessageEvent | Event | CloseEvent) => terminal.write((ev as any).data as string)));
|
|
}
|
|
|
|
if (this._bidirectional) {
|
|
this._disposables.push(terminal.onData(data => this._sendData(data)));
|
|
}
|
|
|
|
this._disposables.push(addSocketListener(this._socket, 'close', () => this.dispose()));
|
|
this._disposables.push(addSocketListener(this._socket, 'error', () => this.dispose()));
|
|
}
|
|
|
|
public dispose(): void {
|
|
this._disposables.forEach(d => d.dispose());
|
|
}
|
|
|
|
private _sendData(data: string): void {
|
|
// TODO: do something better than just swallowing
|
|
// the data if the socket is not in a working condition
|
|
if (this._socket.readyState !== 1) {
|
|
return;
|
|
}
|
|
this._socket.send(data);
|
|
}
|
|
}
|
|
|
|
function addSocketListener(socket: WebSocket, type: string, handler: (this: WebSocket, ev: MessageEvent | Event | CloseEvent) => any): IDisposable {
|
|
socket.addEventListener(type, handler);
|
|
return {
|
|
dispose: () => {
|
|
if (!handler) {
|
|
// Already disposed
|
|
return;
|
|
}
|
|
socket.removeEventListener(type, handler);
|
|
}
|
|
};
|
|
}
|