controller and vsorc data viewers done
[VSoRC/.git] / node_modules / xterm-addon-attach / src / AttachAddon.ts
diff --git a/node_modules/xterm-addon-attach/src/AttachAddon.ts b/node_modules/xterm-addon-attach/src/AttachAddon.ts
new file mode 100644 (file)
index 0000000..117b2b5
--- /dev/null
@@ -0,0 +1,67 @@
+/**
+ * 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;
+}
+
+export class AttachAddon implements ITerminalAddon {
+  private _socket: WebSocket;
+  private _bidirectional: 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;
+  }
+
+  public activate(terminal: Terminal): void {
+    this._disposables.push(
+      addSocketListener(this._socket, 'message', ev => {
+        const data: ArrayBuffer | string = ev.data;
+        terminal.write(typeof data === 'string' ? data : new Uint8Array(data));
+      })
+    );
+
+    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<K extends keyof WebSocketEventMap>(socket: WebSocket, type: K, handler: (this: WebSocket, ev: WebSocketEventMap[K]) => any): IDisposable {
+  socket.addEventListener(type, handler);
+  return {
+    dispose: () => {
+      if (!handler) {
+        // Already disposed
+        return;
+      }
+      socket.removeEventListener(type, handler);
+    }
+  };
+}