import { Directive , ElementRef , OnInit , Input , Output , EventEmitter , HostListener , OnDestroy , OnChanges , AfterViewChecked , SimpleChanges } from '@angular/core' ; import { Subject } from 'rxjs' ; import { debounceTime , takeUntil , filter , map , distinctUntilChanged } from 'rxjs/operators' ; import { MonacoEditorService } from '../../services/monaco-editor.service' ; import { MonacoFile } from '../../entities/file' ; import { MonacoEditorOptions } from '../../entities/editor-options' ; @ Directive ( { selector : 'monaco-editor,[monaco-editor]' } ) export class MonacoEditorDirective implements OnInit , OnDestroy , OnChanges , AfterViewChecked { @ Input ( ) theme : string ; @ Input ( ) file : MonacoFile ; @ Input ( ) options : MonacoEditorOptions ; @ Output ( ) ready = new EventEmitter ( ) ; @ Output ( ) fileChange = new EventEmitter < MonacoFile > ( ) ; private resize$ = new Subject ( ) ; private destroy$ = new Subject ( ) ; constructor ( private monacoEditorService , private editorRef ) { } @ HostListener ( 'window:resize' ) onResize ( ) { this . resize$ . next ( ) ; } param file open ( file ) { this . monacoEditorService . open ( file ) ; } ngOnInit ( ) { this . monacoEditorService . load ( this . editorRef , { theme : this . theme , editor : this . options } ) . subscribe ( ( ) => { this . ready . emit ( ) ; } ) ; this . monacoEditorService . fileChange$ . pipe ( takeUntil ( this . destroy$ ) ) . subscribe ( file => { this . fileChange . emit ( file ) ; } ) ; this . resize$ . pipe ( filter ( ( ) => Boolean ( this . monacoEditorService . editor ) ) , map ( ( ) => ( { width : this . editorRef . nativeElement . clientWidth , height : this . editorRef . nativeElement . clientHeight } ) ) , distinctUntilChanged ( ( a , b ) => a . width === b . width && a . height === b . height ) , debounceTime ( 50 ) , takeUntil ( this . destroy$ ) ) . subscribe ( dimension => { this . monacoEditorService . editor . layout ( dimension ) ; } ) ; } ngOnDestroy ( ) { this . destroy$ . next ( ) ; } ngOnChanges ( changes ) { if ( changes . options ) { this . monacoEditorService . updateOptions ( changes . options . currentValue ) ; } if ( changes . theme ) { this . monacoEditorService . setTheme ( changes . theme . currentValue ) ; } if ( changes . file ) { this . open ( changes . file . currentValue ) ; } } ngAfterViewChecked ( ) { this . resize$ . next ( ) ; } }