X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=webapp%2Fsrc%2Fapp%2Fpages%2Ftargets%2Fterminals%2Fterminal.component.ts;fp=webapp%2Fsrc%2Fapp%2Fpages%2Ftargets%2Fterminals%2Fterminal.component.ts;h=0478a08abc9ea56f5609c89769db243db6a82d0a;hb=069de98bdd926cb25954aad94fe23be0272a7b5e;hp=0000000000000000000000000000000000000000;hpb=6aa5e4ccb5adadcc0cb802c44c1e88a35a20a925;p=src%2Fxds%2Fxds-agent.git diff --git a/webapp/src/app/pages/targets/terminals/terminal.component.ts b/webapp/src/app/pages/targets/terminals/terminal.component.ts new file mode 100644 index 0000000..0478a08 --- /dev/null +++ b/webapp/src/app/pages/targets/terminals/terminal.component.ts @@ -0,0 +1,135 @@ +/** +* @license +* Copyright (C) 2018 "IoT.bzh" +* Author Sebastien Douheret +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { Component, ElementRef, ViewChild, Input, Output, HostListener, EventEmitter, AfterViewInit } from '@angular/core'; +import { Observable } from 'rxjs/Observable'; + +import { Terminal } from 'xterm'; +import * as fit from 'xterm/lib/addons/fit/fit'; + +export interface ITerminalFont { + fontFamily: string; + fontSize: string; + lineHeight: number; + charWidth: number; + charHeight: number; +} + + +@Component({ + selector: 'xds-terminal', + styles: [], + template: ` +
+ `, +}) +export class TerminalComponent implements AfterViewInit { + + private _xterm: Terminal; + private _initDone: boolean; + + @ViewChild('terminalContainer') termContainer: ElementRef; + + @Output() stdin = new EventEmitter(); + @Output() resize = new EventEmitter<{ cols: number, rows: number }>(); + + + constructor() { + this._initDone = false; + Terminal.applyAddon(fit); + + this._xterm = new Terminal({ + cursorBlink: true, + // useStyle: true, + scrollback: 1000, + rows: 24, + cols: 80, + }); + } + + // getting the nativeElement only possible after view init + ngAfterViewInit() { + + // this now finds the #terminal element + this._xterm.open(this.termContainer.nativeElement); + + // the number of rows will determine the size of the terminal screen + (this._xterm).fit(); + + // Bind input key + this._xterm.on('data', (data) => { + // console.log(data.charCodeAt(0)); + this.stdin.emit(this._sanitizeInput(data)); + return false; + }); + + this._initDone = true; + } + + @Input('stdout') + set writeData(data) { + if (this._initDone && data !== undefined) { + this._xterm.write(data); + } + } + + @Input('disable') + set disable(value: boolean) { + if (!this._initDone) { + return; + } + + this._xterm.setOption('disableStdin', value); + + if (value) { + this._xterm.blur(); + } else { + this._xterm.focus(); + } + this._resize(); + } + + @HostListener('window:resize', ['$event']) + onWindowResize(event) { + this._resize(); + } + + /*** Private functions ***/ + + private _sanitizeInput(d) { + // TODO sanitize ? + return d; + } + + private _resize() { + const geom = fit.proposeGeometry(this._xterm); + + // console.log('DEBUG cols ' + String(geom.cols) + ' rows ' + String(geom.rows)); + + if (geom.cols < 0 || geom.cols > 2000 || geom.rows < 0 || geom.rows > 2000) { + return; + } + + // Update xterm size + this._xterm.resize(geom.cols, geom.rows); + + // Send resize event to update remote terminal + this.resize.emit({ cols: geom.cols, rows: geom.rows }); + } + +}