1import {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'; 5var configJSON = require('../../../config.json'); 6if (configJSON.keyType == 'VT100+') { 7 var vt100PlusKey = require('./vt100plus'); 8} 9 10var customKeyHandlers = function(ev) { 11 if (configJSON.keyType == 'VT100+') { 12 return vt100PlusKey.customVT100PlusKey(ev, this); 13 } 14 return true; 15}; 16 17function 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 38// 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') { 42 let TextEncoder = function TextEncoder() {}; 43 TextEncoder.prototype.encode = function encode(str) { 44 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'; 120} 121 122window.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'), 130 'scope': {'path': '=', 'showTabBtn': '=?'}, 131 'controller': [ 132 '$scope', '$cookies', '$window', 'dataService', '$element', 133 function($scope, $cookies, $window, dataService, $element) { 134 $scope.dataService = dataService; 135 136 // See https://github.com/xtermjs/xterm.js/ for available xterm 137 // options 138 139 Terminal.applyAddon(attach); // Apply the `attach` addon 140 Terminal.applyAddon(fit); // Apply the `fit` addon 141 142 var border = 10; 143 var term = new Terminal(); 144 // Should be a reference to <div id="terminal"></div> 145 var terminal = $element[0].firstElementChild.firstElementChild; 146 var customConsole; 147 var charSize; 148 var termContainer; 149 150 term.open(terminal); 151 term.fit(); 152 if (configJSON.customKeyEnable == true) { 153 term.attachCustomKeyEventHandler(customKeyHandlers); 154 } 155 var SOL_THEME = { 156 background: '#19273c', 157 cursor: 'rgba(83, 146, 255, .5)', 158 scrollbar: 'rgba(83, 146, 255, .5)' 159 }; 160 term.setOption('theme', SOL_THEME); 161 var hostname = dataService.getHost().replace('https://', ''); 162 var host = 'wss://' + hostname + '/console0'; 163 var token = $cookies.get('XSRF-TOKEN'); 164 try { 165 var ws = new WebSocket(host, [token]); 166 term.attach(ws); 167 ws.onopen = function() { 168 console.log('websocket opened'); 169 }; 170 ws.onclose = function(event) { 171 console.log( 172 'websocket closed. code: ' + event.code + 173 ' reason: ' + event.reason); 174 }; 175 } catch (error) { 176 console.log(JSON.stringify(error)); 177 } 178 179 $window.onresize = function() { 180 termContainer = document.getElementById('term-container'); 181 termContainer.style.width = window.innerWidth; 182 termContainer.style.height = window.innerHeight; 183 term.fit(); 184 }; 185 186 $scope.openTerminalWindow = function() { 187 var sol_window = $window.open( 188 '#/server-control/remote-console-window', 189 'Remote Console Window', 190 'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=600,height=550'); 191 192 sol_window.onresize = function() { 193 termContainer = document.getElementById('term-container'); 194 termContainer.style.width = sol_window.innerWidth; 195 termContainer.style.height = sol_window.innerHeight; 196 term.fit(); 197 }; 198 }; 199 } 200 ] 201 }; 202 } 203 ]); 204})(window.angular); 205