You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 line
5.8 KiB
1 line
5.8 KiB
{"version":3,"file":"attach.js","sources":["../../../src/addons/attach/attach.ts","../../../node_modules/browser-pack/_prelude.js"],"sourcesContent":["/**\n * Copyright (c) 2014 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * Implements the attach method, that attaches the terminal to a WebSocket stream.\n */\n\nimport { Terminal, IDisposable } from 'xterm';\nimport { IAttachAddonTerminal } from './Interfaces';\n\n/**\n * Attaches the given terminal to the given socket.\n *\n * @param term The terminal to be attached to the given socket.\n * @param socket The socket to attach the current terminal.\n * @param bidirectional Whether the terminal should send data to the socket as well.\n * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum\n * frequency of 1 rendering per 10ms.\n */\nexport function attach(term: Terminal, socket: WebSocket, bidirectional: boolean, buffered: boolean): void {\n const addonTerminal = <IAttachAddonTerminal>term;\n bidirectional = (typeof bidirectional === 'undefined') ? true : bidirectional;\n addonTerminal.__socket = socket;\n\n addonTerminal.__flushBuffer = () => {\n addonTerminal.write(addonTerminal.__attachSocketBuffer);\n addonTerminal.__attachSocketBuffer = null;\n };\n\n addonTerminal.__pushToBuffer = (data: string) => {\n if (addonTerminal.__attachSocketBuffer) {\n addonTerminal.__attachSocketBuffer += data;\n } else {\n addonTerminal.__attachSocketBuffer = data;\n setTimeout(addonTerminal.__flushBuffer, 10);\n }\n };\n\n // TODO: This should be typed but there seem to be issues importing the type\n let myTextDecoder: any;\n\n addonTerminal.__getMessage = function(ev: MessageEvent): void {\n let str: string;\n\n if (typeof ev.data === 'object') {\n if (!myTextDecoder) {\n myTextDecoder = new TextDecoder();\n }\n if (ev.data instanceof ArrayBuffer) {\n str = myTextDecoder.decode(ev.data);\n displayData(str);\n } else {\n const fileReader = new FileReader();\n\n fileReader.addEventListener('load', () => {\n str = myTextDecoder.decode(fileReader.result);\n displayData(str);\n });\n fileReader.readAsArrayBuffer(ev.data);\n }\n } else if (typeof ev.data === 'string') {\n displayData(ev.data);\n } else {\n throw Error(`Cannot handle \"${typeof ev.data}\" websocket message.`);\n }\n };\n\n /**\n * Push data to buffer or write it in the terminal.\n * This is used as a callback for FileReader.onload.\n *\n * @param str String decoded by FileReader.\n * @param data The data of the EventMessage.\n */\n function displayData(str?: string, data?: string): void {\n if (buffered) {\n addonTerminal.__pushToBuffer(str || data);\n } else {\n addonTerminal.write(str || data);\n }\n }\n\n addonTerminal.__sendData = (data: string) => {\n if (socket.readyState !== 1) {\n return;\n }\n socket.send(data);\n };\n\n addonTerminal._core.register(addSocketListener(socket, 'message', addonTerminal.__getMessage));\n\n if (bidirectional) {\n addonTerminal._core.register(addonTerminal.addDisposableListener('data', addonTerminal.__sendData));\n }\n\n addonTerminal._core.register(addSocketListener(socket, 'close', () => detach(addonTerminal, socket)));\n addonTerminal._core.register(addSocketListener(socket, 'error', () => detach(addonTerminal, socket)));\n}\n\nfunction addSocketListener(socket: WebSocket, type: string, handler: (this: WebSocket, ev: Event) => any): IDisposable {\n socket.addEventListener(type, handler);\n return {\n dispose: () => {\n if (!handler) {\n // Already disposed\n return;\n }\n socket.removeEventListener(type, handler);\n handler = null;\n }\n };\n}\n\n/**\n * Detaches the given terminal from the given socket\n *\n * @param term The terminal to be detached from the given socket.\n * @param socket The socket from which to detach the current terminal.\n */\nexport function detach(term: Terminal, socket: WebSocket): void {\n const addonTerminal = <IAttachAddonTerminal>term;\n addonTerminal.off('data', addonTerminal.__sendData);\n\n socket = (typeof socket === 'undefined') ? addonTerminal.__socket : socket;\n\n if (socket) {\n socket.removeEventListener('message', addonTerminal.__getMessage);\n }\n\n delete addonTerminal.__socket;\n}\n\n\nexport function apply(terminalConstructor: typeof Terminal): void {\n /**\n * Attaches the current terminal to the given socket\n *\n * @param socket The socket to attach the current terminal.\n * @param bidirectional Whether the terminal should send data to the socket as well.\n * @param buffered Whether the rendering of incoming data should happen instantly or at a maximum\n * frequency of 1 rendering per 10ms.\n */\n (<any>terminalConstructor.prototype).attach = function (socket: WebSocket, bidirectional: boolean, buffered: boolean): void {\n attach(this, socket, bidirectional, buffered);\n };\n\n /**\n * Detaches the current terminal from the given socket.\n *\n * @param socket The socket from which to detach the current terminal.\n */\n (<any>terminalConstructor.prototype).detach = function (socket: WebSocket): void {\n detach(this, socket);\n };\n}\n",null],"names":[],"mappings":"ACAA;;;ADmBA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AACA;AAGA;AAEA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAAA;AACA;AACA;AAAA;AACA;AACA;AACA;AASA;AACA;AACA;AACA;AAAA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AACA;AA9EA;AAgFA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AAQA;AACA;AACA;AAEA;AAEA;AACA;AACA;AAEA;AACA;AAXA;AAcA;AASA;AACA;AACA;AAOA;AACA;AACA;AACA;AArBA;"} |