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/*
39TextEncoder/TextDecoder does not support IE.
40Use text-encoding instead in IE
41More detail at https://caniuse.com/#feat=textencoder
42*/
43import {TextDecoder} from 'text-encoding';
44if (!window['TextDecoder']) {
45  window['TextDecoder'] = TextDecoder;
46}
47
48window.angular && (function(angular) {
49  'use strict';
50
51  angular.module('app.common.directives').directive('serialConsole', [
52    function() {
53      return {
54        'restrict': 'E',
55        'template': require('./serial-console.html'),
56        'scope': {'path': '=', 'showTabBtn': '=?'},
57        'controller': [
58          '$scope', '$window', 'dataService', '$element',
59          function($scope, $window, dataService, $element) {
60            $scope.dataService = dataService;
61
62            // See https://github.com/xtermjs/xterm.js/ for available xterm
63            // options
64
65            Terminal.applyAddon(attach);  // Apply the `attach` addon
66            Terminal.applyAddon(fit);     // Apply the `fit` addon
67
68            var border = 10;
69            var term = new Terminal();
70            // Should be a reference to <div id="terminal"></div>
71            var terminal = $element[0].firstElementChild.firstElementChild;
72            var customConsole;
73            var charSize;
74            var termContainer;
75
76            term.open(terminal);
77            customConsole = configJSON.customConsoleDisplaySize;
78
79            if (customConsole != null) {
80              charSize = measureChar(term);
81              termContainer = document.getElementById('term-container');
82              if (termContainer != null) {
83                if (customConsole.width) {
84                  termContainer.style.width =
85                      (charSize.width * customConsole.width + border) + 'px';
86                }
87                if (customConsole.height) {
88                  terminal.style.height =
89                      (charSize.height * customConsole.height + border) + 'px';
90                }
91              }
92            }
93            term.fit();
94            if (configJSON.customKeyEnable == true) {
95              term.attachCustomKeyEventHandler(customKeyHandlers);
96            }
97            var SOL_THEME = {
98              background: '#19273c',
99              cursor: 'rgba(83, 146, 255, .5)',
100              scrollbar: 'rgba(83, 146, 255, .5)'
101            };
102            term.setOption('theme', SOL_THEME);
103            var hostname = dataService.getHost().replace('https://', '');
104            var host = 'wss://' + hostname + '/console0';
105            try {
106              var ws = new WebSocket(host);
107              term.attach(ws);
108              ws.onopen = function() {
109                console.log('websocket opened');
110              };
111              ws.onclose = function(event) {
112                console.log(
113                    'websocket closed. code: ' + event.code +
114                    ' reason: ' + event.reason);
115              };
116            } catch (error) {
117              console.log(JSON.stringify(error));
118            }
119            $scope.openTerminalWindow = function() {
120              $window.open(
121                  '#/server-control/remote-console-window',
122                  'Remote Console Window',
123                  'directories=no,titlebar=no,toolbar=no,location=no,status=no,menubar=no,scrollbars=no,resizable=yes,width=600,height=550');
124            };
125          }
126        ]
127      };
128    }
129  ]);
130})(window.angular);
131