1- import { Component , ElementRef , OnInit , Input , SimpleChange , EventEmitter } from '@angular/core' ;
1+ import {
2+ Component , ElementRef , OnInit , Input , SimpleChange , EventEmitter , NgZone } from '@angular/core' ;
23import { ISlimScrollOptions , SlimScrollEvent } from 'ngx-slimscroll' ;
4+
35import * as AnsiUp from 'ansi_up' ;
46
57@Component ( {
@@ -12,8 +14,9 @@ export class AppTerminalComponent implements OnInit {
1214 au : any ;
1315 scrollOptions : ISlimScrollOptions ;
1416 scrollEvents : EventEmitter < SlimScrollEvent > ;
17+ commands : { command : string , visible : boolean , output : string } [ ] ;
1518
16- constructor ( private elementRef : ElementRef ) {
19+ constructor ( private elementRef : ElementRef , private ngZone : NgZone ) {
1720 this . scrollOptions = {
1821 position : 'right' ,
1922 barBackground : '#11121A' ,
@@ -35,26 +38,63 @@ export class AppTerminalComponent implements OnInit {
3538 ngOnInit ( ) {
3639 this . au = new AnsiUp . default ( ) ;
3740 this . au . use_classes = true ;
41+ this . commands = [ ] ;
3842 }
3943
4044 ngOnChanges ( changes : SimpleChange ) {
4145 if ( ! this . data ) {
4246 return ;
4347 }
4448
45- const el = this . elementRef . nativeElement . querySelector ( '.window-terminal-container' ) ;
46- if ( typeof this . data . clear !== 'undefined' ) {
47- el . innerHTML = '' ;
48- } else {
49- el . innerHTML += this . au . ansi_to_html ( this . data ) ;
49+ this . ngZone . run ( ( ) => {
50+ const el = this . elementRef . nativeElement . querySelector ( '.window-terminal-container' ) ;
51+ if ( typeof this . data . clear !== 'undefined' ) {
52+ el . innerHTML = '' ;
53+ } else {
54+ let output : string = this . au . ansi_to_html ( this . data ) ;
55+ if ( output ) {
56+ if ( this . commands . length > 0 ) {
57+ if ( output . indexOf ( '==>' ) !== - 1 ) {
58+ let command = output . split ( '</span>' ) [ 0 ] + '</span>' ;
59+ this . commands . push ( {
60+ command : command ,
61+ visible : true ,
62+ output : output
63+ } ) ;
64+ } else {
65+ this . commands [ this . commands . length - 1 ] . command += ` ${ output } ` ;
66+ }
67+ } else {
68+ let regexp = / < s p a n ( .* ) = = & g t ; / gi;
69+ regexp . lastIndex = 1 ;
70+ let match = regexp . exec ( output ) ;
71+ if ( match ) {
72+ let indexEnd = match . index ;
73+ let indexStart = 0 ;
74+ while ( indexEnd >= 0 ) {
75+ let log = output . substring ( indexStart , indexEnd ) ;
76+ let command = log . split ( '</span>' ) [ 0 ] + '</span>' ;
77+ this . commands . push ( {
78+ command : command ,
79+ visible : true ,
80+ output : log
81+ } ) ;
82+ indexStart = indexEnd ;
83+ indexEnd = regexp . exec ( output ) . index ;
84+ }
85+ }
86+ }
87+ }
5088
51- const recalculateEvent = new SlimScrollEvent ( { type : 'recalculate' } ) ;
52- const bottomEvent = new SlimScrollEvent ( { type : 'scrollToBottom' , duration : 300 } ) ;
89+ const recalculateEvent = new SlimScrollEvent ( { type : 'recalculate' } ) ;
90+ const bottomEvent = new SlimScrollEvent ( { type : 'scrollToBottom' , duration : 300 } ) ;
5391
54- setTimeout ( ( ) => {
55- this . scrollEvents . emit ( recalculateEvent ) ;
56- this . scrollEvents . emit ( bottomEvent ) ;
57- } ) ;
58- }
92+ setTimeout ( ( ) => el . scrollTop = el . scrollHeight ) ;
93+ }
94+ } ) ;
95+ }
96+
97+ toogleCommand ( index : number ) {
98+ this . commands [ index ] . visible = ! this . commands [ index ] . visible ;
5999 }
60100}
0 commit comments