blob: 8d322f1d6bff7acf9c03f3282000f5de500b3ccf [file] [log] [blame]
beccabroek457ca042018-09-07 17:18:24 -05001import {Terminal} from 'xterm';
2import style from 'xterm/dist/xterm.css';
3import * as attach from 'xterm/lib/addons/attach/attach';
4import * as fit from 'xterm/lib/addons/fit/fit';
Yang Cheng6d1d6002019-02-27 11:16:24 +08005var configJSON = require('../../../config.json');
6if (configJSON.keyType == 'VT100+') {
7 var vt100PlusKey = require('./vt100plus');
8}
beccabroek457ca042018-09-07 17:18:24 -05009
Yang Cheng6d1d6002019-02-27 11:16:24 +080010var customKeyHandlers = function(ev) {
11 if (configJSON.keyType == 'VT100+') {
12 return vt100PlusKey.customVT100PlusKey(ev, this);
13 }
14 return true;
15};
beccabroek75697f92018-09-04 09:34:44 -050016
Yang Cheng511a2bb2019-03-06 22:20:35 +080017function measureChar(term) {
18 var span = document.createElement('span');
19 var fontFamily = 'courier-new';
20 var fontSize = 15;
21 var rect;
22
23 span.textContent = 'W';
24 try {
25 fontFamily = term.getOption('fontFamily');
26 fontSize = term.getOption('fontSize');
27 } catch (err) {
28 console.log('get option failure');
29 }
30 span.style.fontFamily = fontFamily;
31 span.style.fontSize = fontSize + 'px';
32 document.body.appendChild(span);
33 rect = span.getBoundingClientRect();
34 document.body.removeChild(span);
35 return rect;
36}
37
Ed Tanousd8713592020-07-16 07:33:07 -070038// Add a TextEncoder polyfill to handle ie9 properly. (does anyone still use
39// that anymore? Grabbed from
40// https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder#Polyfill
41if (typeof TextEncoder === 'undefined') {
Ed Tanous6bb1f472020-08-06 06:00:45 +000042 let TextEncoder = function TextEncoder() {};
Ed Tanousd8713592020-07-16 07:33:07 -070043 TextEncoder.prototype.encode = function encode(str) {
Ed Tanousd8713592020-07-16 07:33:07 -070044 var Len = str.length, resPos = -1;
45 // The Uint8Array's length must be at least 3x the length of the string
46 // because an invalid UTF-16
47 // takes up the equivelent space of 3 UTF-8 characters to encode it
48 // properly. However, Array's have an auto expanding length and 1.5x should
49 // be just the right balance for most uses.
50 var resArr = typeof Uint8Array === 'undefined' ? new Array(Len * 1.5) :
51 new Uint8Array(Len * 3);
52 for (var point = 0, nextcode = 0, i = 0; i !== Len;) {
53 point = str.charCodeAt(i), i += 1;
54 if (point >= 0xD800 && point <= 0xDBFF) {
55 if (i === Len) {
56 resArr[resPos += 1] = 0xef /*0b11101111*/;
57 resArr[resPos += 1] = 0xbf /*0b10111111*/;
58 resArr[resPos += 1] = 0xbd /*0b10111101*/;
59 break;
60 }
61 // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
62 nextcode = str.charCodeAt(i);
63 if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) {
64 point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000;
65 i += 1;
66 if (point > 0xffff) {
67 resArr[resPos += 1] = (0x1e /*0b11110*/ << 3) | (point >>> 18);
68 resArr[resPos += 1] =
69 (0x2 /*0b10*/ << 6) | ((point >>> 12) & 0x3f /*0b00111111*/);
70 resArr[resPos += 1] =
71 (0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f /*0b00111111*/);
72 resArr[resPos += 1] =
73 (0x2 /*0b10*/ << 6) | (point & 0x3f /*0b00111111*/);
74 continue;
75 }
76 } else {
77 resArr[resPos += 1] = 0xef /*0b11101111*/;
78 resArr[resPos += 1] = 0xbf /*0b10111111*/;
79 resArr[resPos += 1] = 0xbd /*0b10111101*/;
80 continue;
81 }
82 }
83 if (point <= 0x007f) {
84 resArr[resPos += 1] = (0x0 /*0b0*/ << 7) | point;
85 } else if (point <= 0x07ff) {
86 resArr[resPos += 1] = (0x6 /*0b110*/ << 5) | (point >>> 6);
87 resArr[resPos += 1] =
88 (0x2 /*0b10*/ << 6) | (point & 0x3f /*0b00111111*/);
89 } else {
90 resArr[resPos += 1] = (0xe /*0b1110*/ << 4) | (point >>> 12);
91 resArr[resPos += 1] =
92 (0x2 /*0b10*/ << 6) | ((point >>> 6) & 0x3f /*0b00111111*/);
93 resArr[resPos += 1] =
94 (0x2 /*0b10*/ << 6) | (point & 0x3f /*0b00111111*/);
95 }
96 }
97 if (typeof Uint8Array !== 'undefined')
98 return resArr.subarray(0, resPos + 1);
99 // else // IE 6-9
100 resArr.length = resPos + 1; // trim off extra weight
101 return resArr;
102 };
103 TextEncoder.prototype.toString = function() {
104 return '[object TextEncoder]'
105 };
106 try { // Object.defineProperty only works on DOM prototypes in IE8
107 Object.defineProperty(TextEncoder.prototype, 'encoding', {
108 get: function() {
109 if (TextEncoder.prototype.isPrototypeOf(this))
110 return 'utf-8';
111 else
112 throw TypeError('Illegal invocation');
113 }
114 });
115 } catch (e) { /*IE6-8 fallback*/
116 TextEncoder.prototype.encoding = 'utf-8';
117 }
118 if (typeof Symbol !== 'undefined')
119 TextEncoder.prototype[Symbol.toStringTag] = 'TextEncoder';
Kuiying Wangf4a43cc2019-08-26 15:56:10 +0800120}
121
beccabroek75697f92018-09-04 09:34:44 -0500122window.angular && (function(angular) {
123 'use strict';
124
125 angular.module('app.common.directives').directive('serialConsole', [
126 function() {
127 return {
128 'restrict': 'E',
129 'template': require('./serial-console.html'),
beccabroeka788cf02018-09-04 09:38:13 -0500130 'scope': {'path': '=', 'showTabBtn': '=?'},
beccabroek75697f92018-09-04 09:34:44 -0500131 'controller': [
James Feist6a8d1802020-04-08 14:04:19 -0700132 '$scope', '$cookies', '$window', 'dataService', '$element',
133 function($scope, $cookies, $window, dataService, $element) {
beccabroek75697f92018-09-04 09:34:44 -0500134 $scope.dataService = dataService;
135
beccabroek457ca042018-09-07 17:18:24 -0500136 // See https://github.com/xtermjs/xterm.js/ for available xterm
137 // options
beccabroek75697f92018-09-04 09:34:44 -0500138
beccabroek457ca042018-09-07 17:18:24 -0500139 Terminal.applyAddon(attach); // Apply the `attach` addon
140 Terminal.applyAddon(fit); // Apply the `fit` addon
beccabroek75697f92018-09-04 09:34:44 -0500141
Yang Cheng511a2bb2019-03-06 22:20:35 +0800142 var border = 10;
beccabroek457ca042018-09-07 17:18:24 -0500143 var term = new Terminal();
Yoshie Muranaka198ce1f2019-09-20 10:33:04 -0700144 // Should be a reference to <div id="terminal"></div>
145 var terminal = $element[0].firstElementChild.firstElementChild;
Yang Cheng511a2bb2019-03-06 22:20:35 +0800146 var customConsole;
147 var charSize;
148 var termContainer;
149
150 term.open(terminal);
151 customConsole = configJSON.customConsoleDisplaySize;
152
153 if (customConsole != null) {
154 charSize = measureChar(term);
155 termContainer = document.getElementById('term-container');
156 if (termContainer != null) {
157 if (customConsole.width) {
158 termContainer.style.width =
159 (charSize.width * customConsole.width + border) + 'px';
160 }
161 if (customConsole.height) {
162 terminal.style.height =
163 (charSize.height * customConsole.height + border) + 'px';
164 }
165 }
166 }
beccabroek457ca042018-09-07 17:18:24 -0500167 term.fit();
Yang Cheng6d1d6002019-02-27 11:16:24 +0800168 if (configJSON.customKeyEnable == true) {
169 term.attachCustomKeyEventHandler(customKeyHandlers);
170 }
beccabroek457ca042018-09-07 17:18:24 -0500171 var SOL_THEME = {
172 background: '#19273c',
173 cursor: 'rgba(83, 146, 255, .5)',
174 scrollbar: 'rgba(83, 146, 255, .5)'
175 };
176 term.setOption('theme', SOL_THEME);
beccabroek75697f92018-09-04 09:34:44 -0500177 var hostname = dataService.getHost().replace('https://', '');
178 var host = 'wss://' + hostname + '/console0';
James Feist6a8d1802020-04-08 14:04:19 -0700179 var token = $cookies.get('XSRF-TOKEN');
Yoshie Muranakafa8697b2019-08-26 11:09:35 -0700180 try {
James Feist6a8d1802020-04-08 14:04:19 -0700181 var ws = new WebSocket(host, [token]);
Yoshie Muranakafa8697b2019-08-26 11:09:35 -0700182 term.attach(ws);
183 ws.onopen = function() {
184 console.log('websocket opened');
185 };
186 ws.onclose = function(event) {
187 console.log(
188 'websocket closed. code: ' + event.code +
189 ' reason: ' + event.reason);
190 };
191 } catch (error) {
192 console.log(JSON.stringify(error));
193 }
beccabroeka788cf02018-09-04 09:38:13 -0500194 $scope.openTerminalWindow = function() {
195 $window.open(
196 '#/server-control/remote-console-window',
197 'Remote Console Window',
198 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=600,height=550');
199 };
beccabroek75697f92018-09-04 09:34:44 -0500200 }
201 ]
202 };
203 }
204 ]);
205})(window.angular);