import { Component , ElementRef , EventEmitter , Inject , Input , Output , Renderer2 , ViewChild } from '@angular/core' ; import { AngularEditorService , UploadResponse } from './angular-editor.service' ; import { HttpResponse , HttpEvent } from '@angular/common/http' ; import { DOCUMENT } from '@angular/common' ; import { CustomClass } from './config' ; import { SelectOption } from './ae-select/ae-select.component' ; import { Observable } from 'rxjs' ; @ Component ( { selector : 'angular-editor-toolbar' , templateUrl : './angular-editor-toolbar.component.html' , styleUrls : [ './angular-editor-toolbar.component.scss' ] , } ) export class AngularEditorToolbarComponent { htmlMode = false ; linkSelected = false ; block = 'default' ; fontName = 'Times New Roman' ; fontSize = '3' ; foreColour ; backColor ; headings : SelectOption [ ] = [ { label : 'Heading 1' , value : 'h1' , } , { label : 'Heading 2' , value : 'h2' , } , { label : 'Heading 3' , value : 'h3' , } , { label : 'Heading 4' , value : 'h4' , } , { label : 'Heading 5' , value : 'h5' , } , { label : 'Heading 6' , value : 'h6' , } , { label : 'Heading 7' , value : 'h7' , } , { label : 'Paragraph' , value : 'p' , } , { label : 'Predefined' , value : 'pre' } , { label : 'Standard' , value : 'div' } , { label : 'default' , value : 'default' } ] ; fontSizes : SelectOption [ ] = [ { label : '1' , value : '1' , } , { label : '2' , value : '2' , } , { label : '3' , value : '3' , } , { label : '4' , value : '4' , } , { label : '5' , value : '5' , } , { label : '6' , value : '6' , } , { label : '7' , value : '7' , } ] ; customClassId = '-1' ; _customClasses : CustomClass [ ] ; customClassList : SelectOption [ ] = [ { label : '' , value : '' } ] ; tagMap = { BLOCKQUOTE : 'indent' , A : 'link' } ; select = [ 'H1' , 'H2' , 'H3' , 'H4' , 'H5' , 'H6' , 'P' , 'PRE' , 'DIV' ] ; buttons = [ 'bold' , 'italic' , 'underline' , 'strikeThrough' , 'subscript' , 'superscript' , 'justifyLeft' , 'justifyCenter' , 'justifyRight' , 'justifyFull' , 'indent' , 'outdent' , 'insertUnorderedList' , 'insertOrderedList' , 'link' ] ; @ Input ( ) id : string ; @ Input ( ) uploadUrl : string ; @ Input ( ) upload : ( file : File ) => Observable < HttpEvent < UploadResponse > > ; @ Input ( ) showToolbar : boolean ; @ Input ( ) fonts : SelectOption [ ] = [ { label : '' , value : '' } ] ; @ Input ( ) set customClasses ( classes ) { if ( classes ) { this . _customClasses = classes ; this . customClassList = this . _customClasses . map ( ( x , i ) => ( { label : x . name , value : i . toString ( ) } ) ) ; this . customClassList . unshift ( { label : 'Clear Class' , value : '-1' } ) ; } } @ Input ( ) set defaultFontName ( value ) { if ( value ) { this . fontName = value ; } } @ Input ( ) set defaultFontSize ( value ) { if ( value ) { this . fontSize = value ; } } @ Input ( ) hiddenButtons : string [ ] [ ] ; @ Output ( ) execute : EventEmitter < string > = new EventEmitter < string > ( ) ; @ ViewChild ( 'fileInput' , { static : true } ) myInputFile : ElementRef ; public get isLinkButtonDisabled ( ) : boolean { return this . htmlMode || ! Boolean ( this . editorService . selectedText ) ; } constructor ( private r , private editorService , private er , @ Inject ( DOCUMENT ) private doc ) { } param command triggerCommand ( command ) { this . execute . emit ( command ) ; } /**
     * highlight editor buttons when cursor moved or positioning
     */ triggerButtons ( ) { if ( ! this . showToolbar ) { return ; } this . buttons . forEach ( e => { const result = this . doc . queryCommandState ( e ) ; const elementById = this . doc . getElementById ( e + '-' + this . id ) ; if ( result ) { this . r . addClass ( elementById , 'active' ) ; } else { this . r . removeClass ( elementById , 'active' ) ; } } ) ; } /**
     * trigger highlight editor buttons when cursor moved or positioning in block
     */ triggerBlocks ( nodes ) { if ( ! this . showToolbar ) { return ; } this . linkSelected = nodes . findIndex ( x => x . nodeName === 'A' ) > - 1 ; let found = false ; this . select . forEach ( y => { const node = nodes . find ( x => x . nodeName === y ) ; if ( node !== undefined && y === node . nodeName ) { if ( found === false ) { this . block = node . nodeName . toLowerCase ( ) ; found = true ; } } else if ( found === false ) { this . block = 'default' ; } } ) ; found = false ; if ( this . _customClasses ) { this . _customClasses . forEach ( ( y , index ) => { const node = nodes . find ( x => { if ( x instanceof Element ) { return x . className === y . class ; } } ) ; if ( node !== undefined ) { if ( found === false ) { this . customClassId = index . toString ( ) ; found = true ; } } else if ( found === false ) { this . customClassId = '-1' ; } } ) ; } Object . keys ( this . tagMap ) . map ( e => { const elementById = this . doc . getElementById ( this . tagMap [ e ] + '-' + this . id ) ; const node = nodes . find ( x => x . nodeName === e ) ; if ( node !== undefined && e === node . nodeName ) { this . r . addClass ( elementById , 'active' ) ; } else { this . r . removeClass ( elementById , 'active' ) ; } } ) ; this . foreColour = this . doc . queryCommandValue ( 'ForeColor' ) ; this . fontSize = this . doc . queryCommandValue ( 'FontSize' ) ; this . fontName = this . doc . queryCommandValue ( 'FontName' ) . replace ( /"/g , '' ) ; this . backColor = this . doc . queryCommandValue ( 'backColor' ) ; } /**
     * insert URL link
     */ insertUrl ( ) { let url = 'https:\/\/' ; const selection = this . editorService . savedSelection ; if ( selection && selection . commonAncestorContainer . parentElement . nodeName === 'A' ) { const parent = selection . commonAncestorContainer . parentElement as HTMLAnchorElement ; if ( parent . href !== '' ) { url = parent . href ; } } url = prompt ( 'Insert URL link' , url ) ; if ( url && url !== '' && url !== 'https://' ) { this . editorService . createLink ( url ) ; } } /**
     * insert Video link
     */ insertVideo ( ) { this . execute . emit ( '' ) ; const url = prompt ( 'Insert Video link' , `https://` ) ; if ( url && url !== '' && url !== `https://` ) { this . editorService . insertVideo ( url ) ; } } /** insert color */ insertColor ( color , where ) { this . editorService . insertColor ( color , where ) ; this . execute . emit ( '' ) ; } param foreColor setFontName ( foreColor ) { this . editorService . setFontName ( foreColor ) ; this . execute . emit ( '' ) ; } param fontSize setFontSize ( fontSize ) { this . editorService . setFontSize ( fontSize ) ; this . execute . emit ( '' ) ; } param m setEditorMode ( m ) { const toggleEditorModeButton = this . doc . getElementById ( 'toggleEditorMode' + '-' + this . id ) ; if ( m ) { this . r . addClass ( toggleEditorModeButton , 'active' ) ; } else { this . r . removeClass ( toggleEditorModeButton , 'active' ) ; } this . htmlMode = m ; } /**
     * Upload image when file is selected.
     */ onFileChanged ( event ) { const file = event . target . files [ 0 ] ; if ( file . type . includes ( 'image/' ) ) { if ( this . upload ) { this . upload ( file ) . subscribe ( ( response ) => this . watchUploadImage ( response , event ) ) ; } else if ( this . uploadUrl ) { this . editorService . uploadImage ( file ) . subscribe ( ( response ) => this . watchUploadImage ( response , event ) ) ; } else { const reader = new FileReader ( ) ; reader . onload = ( e ) => { const fr = e . currentTarget as FileReader ; this . editorService . insertImage ( fr . result . toString ( ) ) ; } ; reader . readAsDataURL ( file ) ; } } } watchUploadImage ( response , event ) { const { imageUrl } = response . body ; this . editorService . insertImage ( imageUrl ) ; event . srcElement . value = null ; } /**
     * Set custom class
     */ setCustomClass ( classId ) { if ( classId === '-1' ) { this . execute . emit ( 'clear' ) ; } else { this . editorService . createCustomClass ( this . _customClasses [ + classId ] ) ; } } isButtonHidden ( name ) { if ( ! name ) { return false ; } if ( ! ( this . hiddenButtons instanceof Array ) ) { return false ; } let result ; for ( const arr of this . hiddenButtons ) { if ( arr instanceof Array ) { result = arr . find ( item => item === name ) ; } if ( result ) { break ; } } return result !== undefined ; } focus ( ) { this . execute . emit ( 'focus' ) ; console . log ( 'focused' ) ; } }