inspec/www/tutorial/app/xterm-terminal/xterm-terminal.component.ts
2016-09-07 17:53:50 +02:00

157 lines
4.7 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Component, OnInit, Input, Output, EventEmitter, SimpleChange } from '@angular/core';
declare var Terminal: any;
@Component({
selector: 'xterm-terminal',
templateUrl: 'app/xterm-terminal/xterm-terminal.component.html',
styleUrls: ['app/xterm-terminal/xterm-terminal.component.css']
})
export class XtermTerminalComponent implements OnInit {
@Input() response: string;
@Input() responsesArray: any;
@Input() shell: string;
@Output() command: EventEmitter<string> = new EventEmitter<string>();
previousCommands: any = [];
last: number;
currentResponse: string;
shellStatus: string;
buffer: string = '';
poppedCommands: any = [];
// xterm variables
terminalContainer: any;
term: any;
optionElements: any;
cols: string;
rows: string;
shellprompt: string = ' $ ';
ngOnInit() {
this.terminalContainer = document.getElementById('terminal-container');
this.cols = '70';
this.rows = '70';
this.createTerminal();
}
ngOnChanges(changes: {[propertyName: string]: SimpleChange}) {
if (changes['response'] && this.term) {
this.currentResponse = changes['response'].currentValue;
this.term.writeln(this.currentResponse);
this.setPrompt();
}
}
createTerminal() {
while (this.terminalContainer.children.length) {
this.terminalContainer.removeChild(this.terminalContainer.children[0]);
}
this.term = new Terminal({
cursorBlink: true
});
this.term.open(this.terminalContainer);
this.term.fit();
var initialGeometry = this.term.proposeGeometry(),
cols = initialGeometry.cols,
rows = initialGeometry.rows;
this.cols = cols;
this.rows = rows;
this.runFakeTerminal()
}
runFakeTerminal() {
if (this.term._initialized) {
return;
}
this.term._initialized = true;
this.setPrompt();
}
setPrompt() {
this.buffer = '';
if (this.shell === 'inspec-shell') {
this.term.write(" " + '\r\ninspec> ');
} else {
this.term.write(this.shellprompt);
}
}
onKey(ev) {
var shell = null
var printable = ['Alt', 'Control', 'Meta', 'Shift', 'CapsLock', 'Tab', 'Escape', 'ArrowLeft', 'ArrowRight'].indexOf(ev.key) == -1
// on enter, save command to array and send current value of buffer
// to parent component (app). if the command is the same as the previous command
// entered, we just diplay the currentResponse. the reason this is being done here and
// not in the app component is because the ngOnChanges that tracks the value of the
// emitted event won't recognize that there has been a change if it is the same.
if (ev.keyCode == 13) {
this.previousCommands.push(this.buffer);
this.term.write('\r\n');
if (this.previousCommands.length > 1) {
this.last = this.previousCommands.length - 2
}
if (this.buffer === this.previousCommands[this.last]) {
// if the command is next or last, we still want to emit
// the value, since the parent component is responsible
// for interpreting that value and displaying the correct instructions
if (this.buffer.match(/^next\s*/) || this.buffer.match(/^prev\s*/)) {
this.command.emit(this.buffer);
} else {
this.term.writeln(this.currentResponse);
this.setPrompt();
}
}
else {
this.command.emit(this.buffer);
}
}
// on backspace, pop characters from buffer
else if (ev.keyCode == 8) {
if (this.term.x > 2) {
this.buffer = this.buffer.substr(0, this.buffer.length-1);
this.term.write('\b \b');
}
}
// on up arrow, delete anything on line and print previous command
// and push last to poppedCommands
else if (ev.keyCode === 38) {
let last;
if (this.previousCommands.length > 0) {
last = this.previousCommands.pop();
this.poppedCommands.push(last);
} else {
last = '';
}
let letters = this.term.x - 3;
for (var i = 0; i < letters; i++) {
this.term.write('\b \b');
}
this.term.write(last);
}
// on down arrow, delete anything on line and print from popped command
// and push previous to previousCommands
else if (ev.keyCode === 40) {
let previous;
if (this.poppedCommands.length > 0) {
previous = this.poppedCommands.pop();
this.previousCommands.push(previous);
} else {
previous = '';
}
let letters = this.term.x - 3;
for (var i = 0; i < letters; i++) {
this.term.write('\b \b');
}
this.term.write(previous);
}
// write each character on prompt line
else if (printable) {
this.term.write(ev.key);
this.buffer += ev.key;
}
}
}