3 * Copyright (C) 2018 "IoT.bzh"
4 * Author Sebastien Douheret <sebastien@iot.bzh>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 import { Component, ElementRef, ViewChild, Input, Output, HostListener, EventEmitter, AfterViewInit } from '@angular/core';
20 import { Observable } from 'rxjs/Observable';
22 import { Terminal } from 'xterm';
23 import * as fit from 'xterm/lib/addons/fit/fit';
25 export interface ITerminalFont {
35 selector: 'xds-terminal',
38 <div #terminalContainer></div>
41 export class TerminalComponent implements AfterViewInit {
43 private _xterm: Terminal;
44 private _initDone: boolean;
46 @ViewChild('terminalContainer') termContainer: ElementRef;
48 @Output() stdin = new EventEmitter<any>();
49 @Output() resize = new EventEmitter<{ cols: number, rows: number }>();
53 this._initDone = false;
54 Terminal.applyAddon(fit);
56 this._xterm = new Terminal({
65 // getting the nativeElement only possible after view init
68 // this now finds the #terminal element
69 this._xterm.open(this.termContainer.nativeElement);
71 // the number of rows will determine the size of the terminal screen
72 (<any>this._xterm).fit();
75 this._xterm.on('data', (data) => {
76 // console.log(data.charCodeAt(0));
77 this.stdin.emit(this._sanitizeInput(data));
81 this._initDone = true;
86 if (this._initDone && data !== undefined) {
87 this._xterm.write(data);
92 set disable(value: boolean) {
93 if (!this._initDone) {
97 this._xterm.setOption('disableStdin', value);
107 @HostListener('window:resize', ['$event'])
108 onWindowResize(event) {
112 /*** Private functions ***/
114 private _sanitizeInput(d) {
120 const geom = fit.proposeGeometry(this._xterm);
122 // console.log('DEBUG cols ' + String(geom.cols) + ' rows ' + String(geom.rows));
124 if (geom.cols < 0 || geom.cols > 2000 || geom.rows < 0 || geom.rows > 2000) {
129 this._xterm.resize(geom.cols, geom.rows);
131 // Send resize event to update remote terminal
132 this.resize.emit({ cols: geom.cols, rows: geom.rows });