ngx-editor
Version:
WYSIWYG Editor for Angular Applications
1 lines • 45.4 kB
Source Map (JSON)
{"version":3,"sources":["ng://ngx-editor/app/ngx-editor/common/utils/ngx-editor.utils.ts","ng://ngx-editor/app/ngx-editor/common/services/command-executor.service.ts","ng://ngx-editor/app/ngx-editor/common/services/message.service.ts","ng://ngx-editor/app/ngx-editor/common/ngx-editor.defaults.ts","ng://ngx-editor/app/ngx-editor/ngx-editor.component.ts","ng://ngx-editor/app/ngx-editor/ngx-grippie/ngx-grippie.component.ts","ng://ngx-editor/app/ngx-editor/ngx-editor-message/ngx-editor-message.component.ts","ng://ngx-editor/app/ngx-editor/ngx-editor-toolbar/ngx-editor-toolbar.component.ts","ng://ngx-editor/app/ngx-editor/ngx-editor.module.ts","ng://ngx-editor/app/ngx-editor/validators/maxlength-validator.ts"],"names":["canEnableToolbarOptions","value","toolbar","filter","array","indexOf","length","saveSelection","window","getSelection","sel","getRangeAt","rangeCount","document","createRange","restoreSelection","range","removeAllRanges","addRange","select","getEditorConfiguration","ngxEditorConfig","input","i","undefined","hasOwnProperty","canResize","resizer","CommandExecutorService","_http","this","prototype","execute","command","savedSelection","Error","execCommand","insertImage","imageURI","Utils.restoreSelection","insertVideo","videParams","isYoutubeLink","videoUrl","youtubeURL","width","height","insertHtml","checkTagSupportInBrowser","isValidURL","videoSrc","url","test","uploadImage","file","endPoint","formData","FormData","append","req","HttpRequest","reportProgress","request","createLink","params","urlNewTab","newUrl","urlLink","urlText","type","insertColor","color","where","checkSelection","setFontSize","fontSize","deletedValue","deleteAndGetElement","isNumeric","fontPx","setFontName","fontName","fontFamily","html","slectedText","toString","deleteContents","tag","createElement","HTMLUnknownElement","Injectable","HttpClient","MessageService","Subject","getMessage","message","asObservable","sendMessage","next","clearMessageIn","milliseconds","setTimeout","_this","editable","spellcheck","minHeight","minWidth","translate","enableToolbar","showToolbar","placeholder","imageEndPoint","NgxEditorComponent","_messageService","_commandExecutor","_renderer","EventEmitter","Utils","onTextAreaFocus","focus","emit","onEditorFocus","textArea","nativeElement","onContentChange","innerHTML","onChange","togglePlaceholder","onTextAreaBlur","Utils.saveSelection","onTouched","blur","resizeTextArea","offsetY","newHeight","parseInt","style","executeCommand","commandName","error","writeValue","refreshView","registerOnChange","fn","registerOnTouched","normalizedValue","setProperty","removeClass","ngxWrapper","addClass","getCollectiveParams","ngOnInit","config","offsetHeight","Component","args","selector","template","providers","provide","NG_VALUE_ACCESSOR","useExisting","forwardRef","multi","Renderer2","Input","Output","ViewChild","NgxGrippieComponent","_editorComponent","onMouseMove","event","grabber","clientY","oldY","onMouseUp","onResize","preventDefault","HostListener","NgxEditorMessageComponent","subscribe","ngxMessage","clearMessage","NgxEditorToolbarComponent","_popOverConfig","_formBuilder","_commandExecutorService","outsideClick","placement","container","Utils.canEnableToolbarOptions","triggerCommand","buildUrlForm","urlForm","group","Validators","required","insertLink","urlPopover","hide","buildImageForm","imageForm","imageUrl","buildVideoForm","videoForm","onFileChange","e","uploadComplete","isUploading","target","files","updloadPercentage","Math","round","loaded","total","HttpResponse","body","imagePopover","videoPopover","colorPopover","fontSizePopover","PopoverConfig","FormBuilder","NgxEditorModule","NgModule","imports","CommonModule","FormsModule","ReactiveFormsModule","PopoverModule","forRoot","declarations","exports","MaxLengthValidator","maxlength","options","control","innerText","DOMParser","parseFromString","excludeLineBreaks","replace","concatWhiteSpaces","excludeWhiteSpaces","ngxEditor","allowedLength","textLength"],"mappings":"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","sourcesContent":["/**\n * enable or disable toolbar based on configuration\n *\n * @param value toolbar item\n * @param toolbar toolbar configuration object\n */\nexport function canEnableToolbarOptions(value: string, toolbar: any): boolean {\n if (value) {\n if (toolbar['length'] === 0) {\n return true;\n } else {\n const found = toolbar.filter(array => {\n return array.indexOf(value) !== -1;\n });\n\n return found.length ? true : false;\n }\n } else {\n return false;\n }\n}\n\n/**\n * set editor configuration\n *\n * @param value configuration via [config] property\n * @param ngxEditorConfig default editor configuration\n * @param input direct configuration inputs via directives\n */\nexport function getEditorConfiguration(value: any, ngxEditorConfig: any, input: any): any {\n for (const i in ngxEditorConfig) {\n if (i) {\n if (input[i] !== undefined) {\n value[i] = input[i];\n }\n if (!value.hasOwnProperty(i)) {\n value[i] = ngxEditorConfig[i];\n }\n }\n }\n\n return value;\n}\n\n/**\n * return vertical if the element is the resizer property is set to basic\n *\n * @param resizer type of resizer, either basic or stack\n */\nexport function canResize(resizer: string): any {\n if (resizer === 'basic') {\n return 'vertical';\n }\n return false;\n}\n\n/**\n * save selection when the editor is focussed out\n */\nexport function saveSelection(): any {\n if (window.getSelection) {\n const sel = window.getSelection();\n if (sel.getRangeAt && sel.rangeCount) {\n return sel.getRangeAt(0);\n }\n } else if (document.getSelection && document.createRange) {\n return document.createRange();\n }\n return null;\n}\n\n/**\n * restore selection when the editor is focussed in\n *\n * @param range saved selection when the editor is focussed out\n */\nexport function restoreSelection(range): boolean {\n if (range) {\n if (window.getSelection) {\n const sel = window.getSelection();\n sel.removeAllRanges();\n sel.addRange(range);\n return true;\n } else if (document.getSelection && range.select) {\n range.select();\n return true;\n }\n } else {\n return false;\n }\n}\n","import { Injectable } from '@angular/core';\nimport { HttpClient, HttpRequest } from '@angular/common/http';\nimport * as Utils from '../utils/ngx-editor.utils';\n\n@Injectable()\nexport class CommandExecutorService {\n /** saves the selection from the editor when focussed out */\n savedSelection: any = undefined;\n\n /**\n *\n * @param _http HTTP Client for making http requests\n */\n constructor(private _http: HttpClient) { }\n\n /**\n * executes command from the toolbar\n *\n * @param command command to be executed\n */\n execute(command: string): void {\n if (!this.savedSelection && command !== 'enableObjectResizing') {\n throw new Error('Range out of Editor');\n }\n\n if (command === 'enableObjectResizing') {\n document.execCommand('enableObjectResizing', true);\n }\n\n if (command === 'blockquote') {\n document.execCommand('formatBlock', false, 'blockquote');\n }\n\n if (command === 'removeBlockquote') {\n document.execCommand('formatBlock', false, 'div');\n }\n\n document.execCommand(command, false, null);\n }\n\n /**\n * inserts image in the editor\n *\n * @param imageURI url of the image to be inserted\n */\n insertImage(imageURI: string): void {\n if (this.savedSelection) {\n if (imageURI) {\n const restored = Utils.restoreSelection(this.savedSelection);\n if (restored) {\n const inserted = document.execCommand('insertImage', false, imageURI);\n if (!inserted) {\n throw new Error('Invalid URL');\n }\n }\n }\n } else {\n throw new Error('Range out of the editor');\n }\n }\n\n /**\n * inserts image in the editor\n *\n * @param videParams url of the image to be inserted\n */\n insertVideo(videParams: any): void {\n if (this.savedSelection) {\n if (videParams) {\n const restored = Utils.restoreSelection(this.savedSelection);\n if (restored) {\n if (this.isYoutubeLink(videParams.videoUrl)) {\n const youtubeURL = '<iframe width=\"' + videParams.width + '\" height=\"' + videParams.height + '\"'\n + 'src=\"' + videParams.videoUrl + '\"></iframe>';\n this.insertHtml(youtubeURL);\n } else if (this.checkTagSupportInBrowser('video')) {\n\n if (this.isValidURL(videParams.videoUrl)) {\n const videoSrc = '<video width=\"' + videParams.width + '\" height=\"' + videParams.height + '\"'\n + ' controls=\"true\"><source src=\"' + videParams.videoUrl + '\"></video>';\n this.insertHtml(videoSrc);\n } else {\n throw new Error('Invalid video URL');\n }\n\n } else {\n throw new Error('Unable to insert video');\n }\n }\n }\n } else {\n throw new Error('Range out of the editor');\n }\n }\n\n /**\n * checks the input url is a valid youtube URL or not\n *\n * @param url Youtue URL\n */\n private isYoutubeLink(url: string): boolean {\n const ytRegExp = /^(http(s)?:\\/\\/)?((w){3}.)?youtu(be|.be)?(\\.com)?\\/.+/;\n return ytRegExp.test(url);\n }\n\n /**\n * check whether the string is a valid url or not\n * @param url url\n */\n private isValidURL(url: string) {\n const urlRegExp = /(http|https):\\/\\/(\\w+:{0,1}\\w*)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%!\\-\\/]))?/;\n return urlRegExp.test(url);\n }\n\n /**\n * uploads image to the server\n *\n * @param file file that has to be uploaded\n * @param endPoint enpoint to which the image has to be uploaded\n */\n uploadImage(file: File, endPoint: string): any {\n if (!endPoint) {\n throw new Error('Image Endpoint isn`t provided or invalid');\n }\n\n const formData: FormData = new FormData();\n\n if (file) {\n\n formData.append('file', file);\n\n const req = new HttpRequest('POST', endPoint, formData, {\n reportProgress: true\n });\n\n return this._http.request(req);\n\n } else {\n throw new Error('Invalid Image');\n }\n }\n\n /**\n * inserts link in the editor\n *\n * @param params parameters that holds the information for the link\n */\n createLink(params: any): void {\n if (this.savedSelection) {\n /**\n * check whether the saved selection contains a range or plain selection\n */\n if (params.urlNewTab) {\n const newUrl = '<a href=\"' + params.urlLink + '\" target=\"_blank\">' + params.urlText + '</a>';\n\n if (document.getSelection().type !== 'Range') {\n const restored = Utils.restoreSelection(this.savedSelection);\n if (restored) {\n this.insertHtml(newUrl);\n }\n } else {\n throw new Error('Only new links can be inserted. You cannot edit URL`s');\n }\n } else {\n const restored = Utils.restoreSelection(this.savedSelection);\n if (restored) {\n document.execCommand('createLink', false, params.urlLink);\n }\n }\n } else {\n throw new Error('Range out of the editor');\n }\n }\n\n /**\n * insert color either font or background\n *\n * @param color color to be inserted\n * @param where where the color has to be inserted either text/background\n */\n insertColor(color: string, where: string): void {\n if (this.savedSelection) {\n const restored = Utils.restoreSelection(this.savedSelection);\n if (restored && this.checkSelection()) {\n if (where === 'textColor') {\n document.execCommand('foreColor', false, color);\n } else {\n document.execCommand('hiliteColor', false, color);\n }\n }\n } else {\n throw new Error('Range out of the editor');\n }\n }\n\n /**\n * set font size for text\n *\n * @param fontSize font-size to be set\n */\n setFontSize(fontSize: string): void {\n if (this.savedSelection && this.checkSelection()) {\n const deletedValue = this.deleteAndGetElement();\n\n if (deletedValue) {\n const restored = Utils.restoreSelection(this.savedSelection);\n\n if (restored) {\n if (this.isNumeric(fontSize)) {\n const fontPx = '<span style=\"font-size: ' + fontSize + 'px;\">' + deletedValue + '</span>';\n this.insertHtml(fontPx);\n } else {\n const fontPx = '<span style=\"font-size: ' + fontSize + ';\">' + deletedValue + '</span>';\n this.insertHtml(fontPx);\n }\n }\n }\n } else {\n throw new Error('Range out of the editor');\n }\n }\n\n /**\n * set font name/family for text\n *\n * @param fontName font-family to be set\n */\n setFontName(fontName: string): void {\n if (this.savedSelection && this.checkSelection()) {\n const deletedValue = this.deleteAndGetElement();\n\n if (deletedValue) {\n const restored = Utils.restoreSelection(this.savedSelection);\n\n if (restored) {\n if (this.isNumeric(fontName)) {\n const fontFamily = '<span style=\"font-family: ' + fontName + 'px;\">' + deletedValue + '</span>';\n this.insertHtml(fontFamily);\n } else {\n const fontFamily = '<span style=\"font-family: ' + fontName + ';\">' + deletedValue + '</span>';\n this.insertHtml(fontFamily);\n }\n }\n }\n } else {\n throw new Error('Range out of the editor');\n }\n }\n\n /** insert HTML */\n private insertHtml(html: string): void {\n const isHTMLInserted = document.execCommand('insertHTML', false, html);\n\n if (!isHTMLInserted) {\n throw new Error('Unable to perform the operation');\n }\n }\n\n /**\n * check whether the value is a number or string\n * if number return true\n * else return false\n */\n private isNumeric(value: any): boolean {\n return /^-{0,1}\\d+$/.test(value);\n }\n\n /** delete the text at selected range and return the value */\n private deleteAndGetElement(): any {\n let slectedText;\n\n if (this.savedSelection) {\n slectedText = this.savedSelection.toString();\n this.savedSelection.deleteContents();\n return slectedText;\n }\n\n return false;\n }\n\n /** check any slection is made or not */\n private checkSelection(): any {\n const slectedText = this.savedSelection.toString();\n\n if (slectedText.length === 0) {\n throw new Error('No Selection Made');\n }\n\n return true;\n }\n\n /**\n * check tag is supported by browser or not\n *\n * @param tag HTML tag\n */\n private checkTagSupportInBrowser(tag: string): boolean {\n return !(document.createElement(tag) instanceof HTMLUnknownElement);\n }\n\n}\n","import { Injectable } from '@angular/core';\nimport { Subject, Observable } from 'rxjs';\n\n\n/** time in which the message has to be cleared */\nconst DURATION = 7000;\n\n@Injectable()\nexport class MessageService {\n /** variable to hold the user message */\n private message: Subject<string> = new Subject();\n\n constructor() { }\n\n /** returns the message sent by the editor */\n getMessage(): Observable<string> {\n return this.message.asObservable();\n }\n\n /**\n * sends message to the editor\n *\n * @param message message to be sent\n */\n sendMessage(message: string): void {\n this.message.next(message);\n this.clearMessageIn(DURATION);\n }\n\n /**\n * a short interval to clear message\n *\n * @param milliseconds time in seconds in which the message has to be cleared\n */\n private clearMessageIn(milliseconds: number): void {\n setTimeout(() => {\n this.message.next(undefined);\n }, milliseconds);\n }\n}\n","/**\n * toolbar default configuration\n */\nexport const ngxEditorConfig = {\n editable: true,\n spellcheck: true,\n height: 'auto',\n minHeight: '0',\n width: 'auto',\n minWidth: '0',\n translate: 'yes',\n enableToolbar: true,\n showToolbar: true,\n placeholder: 'Enter text here...',\n imageEndPoint: '',\n toolbar: [\n ['bold', 'italic', 'underline', 'strikeThrough', 'superscript', 'subscript'],\n ['fontName', 'fontSize', 'color'],\n ['justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', 'indent', 'outdent'],\n ['cut', 'copy', 'delete', 'removeFormat', 'undo', 'redo'],\n ['paragraph', 'blockquote', 'removeBlockquote', 'horizontalLine', 'orderedList', 'unorderedList'],\n ['link', 'unlink', 'image', 'video']\n ]\n};\n","import {\n Component, OnInit, Input, Output, ViewChild,\n EventEmitter, Renderer2, forwardRef\n} from '@angular/core';\nimport { NG_VALUE_ACCESSOR, ControlValueAccessor } from '@angular/forms';\n\nimport { CommandExecutorService } from './common/services/command-executor.service';\nimport { MessageService } from './common/services/message.service';\n\nimport { ngxEditorConfig } from './common/ngx-editor.defaults';\nimport * as Utils from './common/utils/ngx-editor.utils';\n\n@Component({\n selector: 'app-ngx-editor',\n templateUrl: './ngx-editor.component.html',\n styleUrls: ['./ngx-editor.component.scss'],\n providers: [{\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => NgxEditorComponent),\n multi: true\n }]\n})\n\nexport class NgxEditorComponent implements OnInit, ControlValueAccessor {\n /** Specifies weather the textarea to be editable or not */\n @Input() editable: boolean;\n /** The spellcheck property specifies whether the element is to have its spelling and grammar checked or not. */\n @Input() spellcheck: boolean;\n /** Placeholder for the textArea */\n @Input() placeholder: string;\n /**\n * The translate property specifies whether the content of an element should be translated or not.\n *\n * Check https://www.w3schools.com/tags/att_global_translate.asp for more information and browser support\n */\n @Input() translate: string;\n /** Sets height of the editor */\n @Input() height: string;\n /** Sets minimum height for the editor */\n @Input() minHeight: string;\n /** Sets Width of the editor */\n @Input() width: string;\n /** Sets minimum width of the editor */\n @Input() minWidth: string;\n /**\n * Toolbar accepts an array which specifies the options to be enabled for the toolbar\n *\n * Check ngxEditorConfig for toolbar configuration\n *\n * Passing an empty array will enable all toolbar\n */\n @Input() toolbar: Object;\n /**\n * The editor can be resized vertically.\n *\n * `basic` resizer enables the html5 reszier. Check here https://www.w3schools.com/cssref/css3_pr_resize.asp\n *\n * `stack` resizer enable a resizer that looks like as if in https://stackoverflow.com\n */\n @Input() resizer = 'stack';\n /**\n * The config property is a JSON object\n *\n * All avaibale inputs inputs can be provided in the configuration as JSON\n * inputs provided directly are considered as top priority\n */\n @Input() config = ngxEditorConfig;\n /** Weather to show or hide toolbar */\n @Input() showToolbar: boolean;\n /** Weather to enable or disable the toolbar */\n @Input() enableToolbar: boolean;\n /** Endpoint for which the image to be uploaded */\n @Input() imageEndPoint: string;\n\n /** emits `blur` event when focused out from the textarea */\n @Output() blur: EventEmitter<string> = new EventEmitter<string>();\n /** emits `focus` event when focused in to the textarea */\n @Output() focus: EventEmitter<string> = new EventEmitter<string>();\n\n @ViewChild('ngxTextArea') textArea: any;\n @ViewChild('ngxWrapper') ngxWrapper: any;\n\n Utils: any = Utils;\n\n private onChange: (value: string) => void;\n private onTouched: () => void;\n\n /**\n * @param _messageService service to send message to the editor message component\n * @param _commandExecutor executes command from the toolbar\n * @param _renderer access and manipulate the dom element\n */\n constructor(\n private _messageService: MessageService,\n private _commandExecutor: CommandExecutorService,\n private _renderer: Renderer2) { }\n\n /**\n * events\n */\n onTextAreaFocus(): void {\n this.focus.emit('focus');\n }\n\n /** focus the text area when the editor is focussed */\n onEditorFocus() {\n this.textArea.nativeElement.focus();\n }\n\n /**\n * Executed from the contenteditable section while the input property changes\n * @param html html string from contenteditable\n */\n onContentChange(innerHTML: string): void {\n if (typeof this.onChange === 'function') {\n this.onChange(innerHTML);\n this.togglePlaceholder(innerHTML);\n }\n }\n\n onTextAreaBlur(): void {\n /** save selection if focussed out */\n this._commandExecutor.savedSelection = Utils.saveSelection();\n\n if (typeof this.onTouched === 'function') {\n this.onTouched();\n }\n this.blur.emit('blur');\n }\n\n /**\n * resizing text area\n *\n * @param offsetY vertical height of the eidtable portion of the editor\n */\n resizeTextArea(offsetY: number): void {\n let newHeight = parseInt(this.height, 10);\n newHeight += offsetY;\n this.height = newHeight + 'px';\n this.textArea.nativeElement.style.height = this.height;\n }\n\n /**\n * editor actions, i.e., executes command from toolbar\n *\n * @param commandName name of the command to be executed\n */\n executeCommand(commandName: string): void {\n try {\n this._commandExecutor.execute(commandName);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n }\n\n /**\n * Write a new value to the element.\n *\n * @param value value to be executed when there is a change in contenteditable\n */\n writeValue(value: any): void {\n this.togglePlaceholder(value);\n\n if (value === null || value === undefined || value === '' || value === '<br>') {\n value = null;\n }\n\n this.refreshView(value);\n }\n\n /**\n * Set the function to be called\n * when the control receives a change event.\n *\n * @param fn a function\n */\n registerOnChange(fn: any): void {\n this.onChange = fn;\n }\n\n /**\n * Set the function to be called\n * when the control receives a touch event.\n *\n * @param fn a function\n */\n registerOnTouched(fn: any): void {\n this.onTouched = fn;\n }\n\n /**\n * refresh view/HTML of the editor\n *\n * @param value html string from the editor\n */\n refreshView(value: string): void {\n const normalizedValue = value === null ? '' : value;\n this._renderer.setProperty(this.textArea.nativeElement, 'innerHTML', normalizedValue);\n }\n\n /**\n * toggles placeholder based on input string\n *\n * @param value A HTML string from the editor\n */\n togglePlaceholder(value: any): void {\n if (!value || value === '<br>' || value === '') {\n this._renderer.addClass(this.ngxWrapper.nativeElement, 'show-placeholder');\n } else {\n this._renderer.removeClass(this.ngxWrapper.nativeElement, 'show-placeholder');\n }\n }\n\n /**\n * returns a json containing input params\n */\n getCollectiveParams(): any {\n return {\n editable: this.editable,\n spellcheck: this.spellcheck,\n placeholder: this.placeholder,\n translate: this.translate,\n height: this.height,\n minHeight: this.minHeight,\n width: this.width,\n minWidth: this.minWidth,\n enableToolbar: this.enableToolbar,\n showToolbar: this.showToolbar,\n imageEndPoint: this.imageEndPoint,\n toolbar: this.toolbar\n };\n }\n\n ngOnInit() {\n /**\n * set configuartion\n */\n this.config = this.Utils.getEditorConfiguration(this.config, ngxEditorConfig, this.getCollectiveParams());\n\n this.height = this.height || this.textArea.nativeElement.offsetHeight;\n\n this.executeCommand('enableObjectResizing');\n }\n}\n","import { Component, HostListener } from '@angular/core';\nimport { NgxEditorComponent } from '../ngx-editor.component';\n\n@Component({\n selector: 'app-ngx-grippie',\n templateUrl: './ngx-grippie.component.html',\n styleUrls: ['./ngx-grippie.component.scss']\n})\n\nexport class NgxGrippieComponent {\n /** height of the editor */\n height: number;\n /** previous value befor resizing the editor */\n oldY = 0;\n /** set to true on mousedown event */\n grabber = false;\n\n /**\n * Constructor\n *\n * @param _editorComponent Editor component\n */\n constructor(private _editorComponent: NgxEditorComponent) { }\n\n /**\n *\n * @param event Mouseevent\n *\n * Update the height of the editor when the grabber is dragged\n */\n @HostListener('document:mousemove', ['$event']) onMouseMove(event: MouseEvent) {\n if (!this.grabber) {\n return;\n }\n\n this._editorComponent.resizeTextArea(event.clientY - this.oldY);\n this.oldY = event.clientY;\n }\n\n /**\n *\n * @param event Mouseevent\n *\n * set the grabber to false on mouse up action\n */\n @HostListener('document:mouseup', ['$event']) onMouseUp(event: MouseEvent) {\n this.grabber = false;\n }\n\n @HostListener('mousedown', ['$event']) onResize(event: MouseEvent, resizer?: Function) {\n this.grabber = true;\n this.oldY = event.clientY;\n event.preventDefault();\n }\n\n}\n","import { Component } from '@angular/core';\n\nimport { MessageService } from '../common/services/message.service';\n\n@Component({\n selector: 'app-ngx-editor-message',\n templateUrl: './ngx-editor-message.component.html',\n styleUrls: ['./ngx-editor-message.component.scss']\n})\n\nexport class NgxEditorMessageComponent {\n /** property that holds the message to be displayed on the editor */\n ngxMessage = undefined;\n\n /**\n * @param _messageService service to send message to the editor\n */\n constructor(private _messageService: MessageService) {\n this._messageService.getMessage().subscribe((message: string) => this.ngxMessage = message);\n }\n\n /**\n * clears editor message\n */\n clearMessage(): void {\n this.ngxMessage = undefined;\n }\n}\n","import { Component, Input, Output, EventEmitter, OnInit, ViewChild } from '@angular/core';\nimport { FormBuilder, FormGroup, Validators } from '@angular/forms';\nimport { HttpResponse } from '@angular/common/http';\nimport { PopoverConfig } from 'ngx-bootstrap';\nimport { CommandExecutorService } from '../common/services/command-executor.service';\nimport { MessageService } from '../common/services/message.service';\nimport * as Utils from '../common/utils/ngx-editor.utils';\n\n@Component({\n selector: 'app-ngx-editor-toolbar',\n templateUrl: './ngx-editor-toolbar.component.html',\n styleUrls: ['./ngx-editor-toolbar.component.scss'],\n providers: [PopoverConfig]\n})\n\nexport class NgxEditorToolbarComponent implements OnInit {\n /** holds values of the insert link form */\n urlForm: FormGroup;\n /** holds values of the insert image form */\n imageForm: FormGroup;\n /** holds values of the insert video form */\n videoForm: FormGroup;\n /** set to false when image is being uploaded */\n uploadComplete = true;\n /** upload percentage */\n updloadPercentage = 0;\n /** set to true when the image is being uploaded */\n isUploading = false;\n /** which tab to active for color insetion */\n selectedColorTab = 'textColor';\n /** font family name */\n fontName = '';\n /** font size */\n fontSize = '';\n /** hex color code */\n hexColor = '';\n /** show/hide image uploader */\n isImageUploader = false;\n\n /**\n * Editor configuration\n */\n @Input() config: any;\n @ViewChild('urlPopover') urlPopover;\n @ViewChild('imagePopover') imagePopover;\n @ViewChild('videoPopover') videoPopover;\n @ViewChild('fontSizePopover') fontSizePopover;\n @ViewChild('colorPopover') colorPopover;\n /**\n * Emits an event when a toolbar button is clicked\n */\n @Output() execute: EventEmitter<string> = new EventEmitter<string>();\n\n constructor(private _popOverConfig: PopoverConfig,\n private _formBuilder: FormBuilder,\n private _messageService: MessageService,\n private _commandExecutorService: CommandExecutorService) {\n this._popOverConfig.outsideClick = true;\n this._popOverConfig.placement = 'bottom';\n this._popOverConfig.container = 'body';\n }\n\n /**\n * enable or diable toolbar based on configuration\n *\n * @param value name of the toolbar buttons\n */\n canEnableToolbarOptions(value): boolean {\n return Utils.canEnableToolbarOptions(value, this.config['toolbar']);\n }\n\n /**\n * triggers command from the toolbar to be executed and emits an event\n *\n * @param command name of the command to be executed\n */\n triggerCommand(command: string): void {\n this.execute.emit(command);\n }\n\n /**\n * create URL insert form\n */\n buildUrlForm(): void {\n this.urlForm = this._formBuilder.group({\n urlLink: ['', [Validators.required]],\n urlText: ['', [Validators.required]],\n urlNewTab: [true]\n });\n }\n\n /**\n * inserts link in the editor\n */\n insertLink(): void {\n try {\n this._commandExecutorService.createLink(this.urlForm.value);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n\n /** reset form to default */\n this.buildUrlForm();\n /** close inset URL pop up */\n this.urlPopover.hide();\n }\n\n /**\n * create insert image form\n */\n buildImageForm(): void {\n this.imageForm = this._formBuilder.group({\n imageUrl: ['', [Validators.required]]\n });\n }\n\n /**\n * create insert image form\n */\n buildVideoForm(): void {\n this.videoForm = this._formBuilder.group({\n videoUrl: ['', [Validators.required]],\n height: [''],\n width: ['']\n });\n }\n\n /**\n * Executed when file is selected\n *\n * @param e onChange event\n */\n onFileChange(e): void {\n this.uploadComplete = false;\n this.isUploading = true;\n\n if (e.target.files.length > 0) {\n const file = e.target.files[0];\n\n try {\n this._commandExecutorService.uploadImage(file, this.config.imageEndPoint).subscribe(event => {\n\n if (event.type) {\n this.updloadPercentage = Math.round(100 * event.loaded / event.total);\n }\n\n if (event instanceof HttpResponse) {\n try {\n this._commandExecutorService.insertImage(event.body.url);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n this.uploadComplete = true;\n this.isUploading = false;\n }\n });\n } catch (error) {\n this._messageService.sendMessage(error.message);\n this.uploadComplete = true;\n this.isUploading = false;\n }\n }\n }\n\n /** insert image in the editor */\n insertImage(): void {\n try {\n this._commandExecutorService.insertImage(this.imageForm.value.imageUrl);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n\n /** reset form to default */\n this.buildImageForm();\n /** close inset URL pop up */\n this.imagePopover.hide();\n }\n\n /** insert image in the editor */\n insertVideo(): void {\n try {\n this._commandExecutorService.insertVideo(this.videoForm.value);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n\n /** reset form to default */\n this.buildVideoForm();\n /** close inset URL pop up */\n this.videoPopover.hide();\n }\n\n /** inser text/background color */\n insertColor(color: string, where: string): void {\n try {\n this._commandExecutorService.insertColor(color, where);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n\n this.colorPopover.hide();\n }\n\n /** set font size */\n setFontSize(fontSize: string): void {\n try {\n this._commandExecutorService.setFontSize(fontSize);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n\n this.fontSizePopover.hide();\n }\n\n /** set font Name/family */\n setFontName(fontName: string): void {\n try {\n this._commandExecutorService.setFontName(fontName);\n } catch (error) {\n this._messageService.sendMessage(error.message);\n }\n\n this.fontSizePopover.hide();\n }\n\n ngOnInit() {\n this.buildUrlForm();\n this.buildImageForm();\n this.buildVideoForm();\n }\n}\n","import { NgModule } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule } from '@angular/forms';\nimport { ReactiveFormsModule } from '@angular/forms';\nimport { PopoverModule } from 'ngx-bootstrap';\nimport { NgxEditorComponent } from './ngx-editor.component';\nimport { NgxGrippieComponent } from './ngx-grippie/ngx-grippie.component';\nimport { NgxEditorMessageComponent } from './ngx-editor-message/ngx-editor-message.component';\nimport { NgxEditorToolbarComponent } from './ngx-editor-toolbar/ngx-editor-toolbar.component';\nimport { MessageService } from './common/services/message.service';\nimport { CommandExecutorService } from './common/services/command-executor.service';\n\n@NgModule({\n imports: [CommonModule, FormsModule, ReactiveFormsModule, PopoverModule.forRoot()],\n declarations: [NgxEditorComponent, NgxGrippieComponent, NgxEditorMessageComponent, NgxEditorToolbarComponent],\n exports: [NgxEditorComponent],\n providers: [CommandExecutorService, MessageService]\n})\n\nexport class NgxEditorModule { }\n","import { AbstractControl } from '@angular/forms';\n\ninterface IMaxLengthValidatorOptions {\n excludeLineBreaks?: boolean;\n concatWhiteSpaces?: boolean;\n excludeWhiteSpaces?: boolean;\n}\n\nexport function MaxLengthValidator(maxlength: number, options?: IMaxLengthValidatorOptions) {\n return (control: AbstractControl): { [key: string]: any } | null => {\n const parsedDocument = new DOMParser().parseFromString(control.value, 'text/html');\n let innerText = parsedDocument.body.innerText || '';\n\n // replace all linebreaks\n if (options.excludeLineBreaks) {\n innerText = innerText.replace(/(\\r\\n\\t|\\n|\\r\\t)/gm, '');\n }\n\n // concat multiple whitespaces into a single whitespace\n if (options.concatWhiteSpaces) {\n innerText = innerText.replace(/(\\s\\s+)/gm, ' ');\n }\n\n // remove all whitespaces\n if (options.excludeWhiteSpaces) {\n innerText = innerText.replace(/(\\s)/gm, '');\n }\n\n if (innerText.length > maxlength) {\n return {\n ngxEditor: {\n allowedLength: maxlength,\n textLength: innerText.length\n }\n };\n }\n return null;\n };\n}\n"]}