controller and vsorc data viewers done
[VSoRC/.git] / node_modules / xterm-addon-attach / src / AttachAddon.ts
1 /**
2  * Copyright (c) 2014, 2019 The xterm.js authors. All rights reserved.
3  * @license MIT
4  *
5  * Implements the attach method, that attaches the terminal to a WebSocket stream.
6  */
7
8 import { Terminal, IDisposable, ITerminalAddon } from 'xterm';
9
10 interface IAttachOptions {
11   bidirectional?: boolean;
12 }
13
14 export class AttachAddon implements ITerminalAddon {
15   private _socket: WebSocket;
16   private _bidirectional: boolean;
17   private _disposables: IDisposable[] = [];
18
19   constructor(socket: WebSocket, options?: IAttachOptions) {
20     this._socket = socket;
21     // always set binary type to arraybuffer, we do not handle blobs
22     this._socket.binaryType = 'arraybuffer';
23     this._bidirectional = (options && options.bidirectional === false) ? false : true;
24   }
25
26   public activate(terminal: Terminal): void {
27     this._disposables.push(
28       addSocketListener(this._socket, 'message', ev => {
29         const data: ArrayBuffer | string = ev.data;
30         terminal.write(typeof data === 'string' ? data : new Uint8Array(data));
31       })
32     );
33
34     if (this._bidirectional) {
35       this._disposables.push(terminal.onData(data => this._sendData(data)));
36     }
37
38     this._disposables.push(addSocketListener(this._socket, 'close', () => this.dispose()));
39     this._disposables.push(addSocketListener(this._socket, 'error', () => this.dispose()));
40   }
41
42   public dispose(): void {
43     this._disposables.forEach(d => d.dispose());
44   }
45
46   private _sendData(data: string): void {
47     // TODO: do something better than just swallowing
48     // the data if the socket is not in a working condition
49     if (this._socket.readyState !== 1) {
50       return;
51     }
52     this._socket.send(data);
53   }
54 }
55
56 function addSocketListener<K extends keyof WebSocketEventMap>(socket: WebSocket, type: K, handler: (this: WebSocket, ev: WebSocketEventMap[K]) => any): IDisposable {
57   socket.addEventListener(type, handler);
58   return {
59     dispose: () => {
60       if (!handler) {
61         // Already disposed
62         return;
63       }
64       socket.removeEventListener(type, handler);
65     }
66   };
67 }