@iget/editor
Version:
WYSIWYG Editor for Angular Material applications
819 lines (805 loc) • 60.9 kB
JavaScript
import * as i0 from '@angular/core';
import { Injectable, Component, Inject, EventEmitter, Input, Output, HostListener, forwardRef, ViewChild, NgModule } from '@angular/core';
import * as i7 from '@angular/common';
import { CommonModule } from '@angular/common';
import * as i1 from '@angular/forms';
import { Validators, NG_VALUE_ACCESSOR, FormsModule, ReactiveFormsModule } from '@angular/forms';
import * as i4 from '@angular/material/dialog';
import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog';
import * as i2$1 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import * as i3 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i3$1 from '@angular/material/menu';
import { MatMenuModule } from '@angular/material/menu';
import * as i1$1 from '@angular/platform-browser';
import { Subject } from 'rxjs';
import * as i2 from '@angular/material/form-field';
import * as i5 from '@angular/material/input';
import { MatInputModule } from '@angular/material/input';
const DefaultIgetEditorConfig = {
editable: true,
spellcheck: true,
height: 'auto',
minHeight: '0',
width: 'auto',
minWidth: '0',
translate: 'yes',
enableToolbar: true,
showToolbar: true,
placeholder: 'Enter text here...',
toolbarPosition: 'after',
resizable: true,
toolbar: [
['bold', 'italic', 'underline', 'strikethrough'],
['font', 'fontSize', 'textColor', 'fillColor', 'removeFormat'],
['align'],
['indent', 'quote', 'unorderedList', 'orderedList'],
['undo', 'redo'],
['anchor']
]
};
/**
* enable or disable toolbar based on configuration
*
* @param value toolbar item
* @param toolbar toolbar configuration object
*/
function canEnableToolbarOptions(value, toolbar) {
if (value) {
if (toolbar['length'] === 0) {
return true;
}
else {
const found = toolbar.filter(array => {
return array.indexOf(value) !== -1;
});
return found.length ? true : false;
}
}
else {
return false;
}
}
/**
* return vertical if the element is the resizer property is set to basic
*
* @param resizer type of resizer, either basic or stack
*/
function canResize(resizer) {
if (resizer === 'basic') {
return 'vertical';
}
return false;
}
/**
* save selection when the editor is focussed out
*/
function saveSelection() {
if (window.getSelection) {
const sel = window.getSelection();
if (sel.getRangeAt && sel.rangeCount) {
return sel.getRangeAt(0);
}
}
else if (document.getSelection && document.createRange) {
return document.createRange();
}
return null;
}
/**
* restore selection when the editor is focussed in
*
* @param range saved selection when the editor is focussed out
*/
function restoreSelection(range) {
if (range) {
if (window.getSelection) {
const sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
return true;
}
else if (document.getSelection && range.select) {
range.select();
return true;
}
}
else {
return false;
}
}
var Utils = /*#__PURE__*/Object.freeze({
__proto__: null,
canEnableToolbarOptions: canEnableToolbarOptions,
canResize: canResize,
saveSelection: saveSelection,
restoreSelection: restoreSelection
});
/** time in which the message has to be cleared */
const DURATION = 7000;
class MessageService {
constructor() {
/** variable to hold the user message */
this.message = new Subject();
}
/** returns the message sent by the editor */
getMessage() {
return this.message.asObservable();
}
/**
* sends message to the editor
*
* @param message message to be sent
*/
sendMessage(message) {
this.message.next(message);
this.clearMessageIn(DURATION);
}
/**
* a short interval to clear message
*
* @param milliseconds time in seconds in which the message has to be cleared
*/
clearMessageIn(milliseconds) {
setTimeout(() => {
this.message.next(undefined);
}, milliseconds);
}
}
MessageService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MessageService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
MessageService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MessageService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: MessageService, decorators: [{
type: Injectable
}], ctorParameters: function () { return []; } });
class CommandExecutorService {
constructor() {
/** saves the selection from the editor when focussed out */
this.savedSelection = undefined;
}
/**
* executes command from the toolbar
*
* @param command command to be executed
*/
execute(command) {
if (!this.savedSelection && command !== 'enableObjectResizing') {
throw new Error('Range out of Editor');
}
if (command === 'enableObjectResizing') {
document.execCommand('enableObjectResizing', true);
}
if (command === 'blockquote') {
document.execCommand('formatBlock', false, 'blockquote');
}
if (command === 'removeBlockquote') {
document.execCommand('formatBlock', false, 'div');
}
document.execCommand(command, false, null);
}
/**
* inserts image in the editor
*
* @param imageURI url of the image to be inserted
*/
insertImage(imageURI) {
if (this.savedSelection) {
if (imageURI) {
const restored = restoreSelection(this.savedSelection);
if (restored) {
const inserted = document.execCommand('insertImage', false, imageURI);
if (!inserted) {
throw new Error('Invalid URL');
}
}
}
}
else {
throw new Error('Range out of the editor');
}
}
/**
* inserts image in the editor
*
* @param videParams url of the image to be inserted
*/
insertVideo(videParams) {
if (this.savedSelection) {
if (videParams) {
const restored = restoreSelection(this.savedSelection);
if (restored) {
if (this.isYoutubeLink(videParams.videoUrl)) {
const youtubeURL = '<iframe width="' + videParams.width + '" height="' + videParams.height + '"'
+ 'src="' + videParams.videoUrl + '"></iframe>';
this.insertHtml(youtubeURL);
}
else if (this.checkTagSupportInBrowser('video')) {
if (this.isValidURL(videParams.videoUrl)) {
const videoSrc = '<video width="' + videParams.width + '" height="' + videParams.height + '"'
+ ' controls="true"><source src="' + videParams.videoUrl + '"></video>';
this.insertHtml(videoSrc);
}
else {
throw new Error('Invalid video URL');
}
}
else {
throw new Error('Unable to insert video');
}
}
}
}
else {
throw new Error('Range out of the editor');
}
}
/**
* checks the input url is a valid youtube URL or not
*
* @param url Youtue URL
*/
isYoutubeLink(url) {
const ytRegExp = /^(http(s)?:\/\/)?((w){3}.)?youtu(be|.be)?(\.com)?\/.+/;
return ytRegExp.test(url);
}
/**
* check whether the string is a valid url or not
* @param url url
*/
isValidURL(url) {
const urlRegExp = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
return urlRegExp.test(url);
}
/**
* uploads image to the server
*
* @param file file that has to be uploaded
* @param endPoint enpoint to which the image has to be uploaded
*/
uploadImage(file, endPoint) {
// if (!endPoint) {
// throw new Error('Image Endpoint isn`t provided or invalid');
// }
//
// const formData: FormData = new FormData();
//
// if (file) {
//
// formData.append('file', file);
//
// const req = new HttpRequest('POST', endPoint, formData, {
// reportProgress: true
// });
//
// return this._http.request(req);
//
// } else {
// throw new Error('Invalid Image');
// }
}
/**
* inserts link in the editor
*
* @param params parameters that holds the information for the link
*/
createLink(params) {
if (this.savedSelection) {
/**
* check whether the saved selection contains a range or plain selection
*/
if (params.urlNewTab) {
const newUrl = '<a href="' + params.urlLink + '" target="_blank">' + params.urlText + '</a>';
if (document.getSelection().type !== 'Range') {
const restored = restoreSelection(this.savedSelection);
if (restored) {
this.insertHtml(newUrl);
}
}
else {
throw new Error('Only new links can be inserted. You cannot edit URL`s');
}
}
else {
const restored = restoreSelection(this.savedSelection);
if (restored) {
document.execCommand('createLink', false, params.urlLink);
}
}
}
else {
throw new Error('Range out of the editor');
}
}
/**
* insert color either font or background
*
* @param color color to be inserted
* @param where where the color has to be inserted either text/background
*/
insertColor(color, where) {
if (this.savedSelection) {
const restored = restoreSelection(this.savedSelection);
if (restored && this.checkSelection()) {
if (where === 'textColor') {
document.execCommand('foreColor', false, color);
}
else {
document.execCommand('hiliteColor', false, color);
}
}
}
else {
throw new Error('Range out of the editor');
}
}
/**
* set font size for text
*
* @param fontSize font-size to be set
*/
setFontSize(fontSize) {
if (this.savedSelection && this.checkSelection()) {
const deletedValue = this.deleteAndGetElement();
if (deletedValue) {
const restored = restoreSelection(this.savedSelection);
if (restored) {
if (this.isNumeric(fontSize)) {
const fontPx = '<span style="font-size: ' + fontSize + 'px;">' + deletedValue + '</span>';
this.insertHtml(fontPx);
}
else {
const fontPx = '<span style="font-size: ' + fontSize + ';">' + deletedValue + '</span>';
this.insertHtml(fontPx);
}
}
}
}
else {
throw new Error('Range out of the editor');
}
}
/**
* set font name/family for text
*
* @param fontName font-family to be set
*/
setFontName(fontName) {
if (this.savedSelection && this.checkSelection()) {
const deletedValue = this.deleteAndGetElement();
if (deletedValue) {
const restored = restoreSelection(this.savedSelection);
if (restored) {
if (this.isNumeric(fontName)) {
const fontFamily = '<span style="font-family: ' + fontName + 'px;">' + deletedValue + '</span>';
this.insertHtml(fontFamily);
}
else {
const fontFamily = '<span style="font-family: ' + fontName + ';">' + deletedValue + '</span>';
this.insertHtml(fontFamily);
}
}
}
}
else {
throw new Error('Range out of the editor');
}
}
/** insert HTML */
insertHtml(html) {
const isHTMLInserted = document.execCommand('insertHTML', false, html);
if (!isHTMLInserted) {
throw new Error('Unable to perform the operation');
}
}
/**
* check whether the value is a number or string
* if number return true
* else return false
*/
isNumeric(value) {
return /^-{0,1}\d+$/.test(value);
}
/** delete the text at selected range and return the value */
deleteAndGetElement() {
let slectedText;
if (this.savedSelection) {
slectedText = this.savedSelection.toString();
this.savedSelection.deleteContents();
return slectedText;
}
return false;
}
/** check any slection is made or not */
checkSelection() {
const slectedText = this.savedSelection.toString();
if (slectedText.length === 0) {
throw new Error('No Selection Made');
}
return true;
}
/**
* check tag is supported by browser or not
*
* @param tag HTML tag
*/
checkTagSupportInBrowser(tag) {
return !(document.createElement(tag) instanceof HTMLUnknownElement);
}
}
CommandExecutorService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CommandExecutorService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
CommandExecutorService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CommandExecutorService });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: CommandExecutorService, decorators: [{
type: Injectable
}] });
class LinkDialogComponent {
constructor(formBuilder, data) {
this.formBuilder = formBuilder;
this.data = data;
}
ngOnInit() {
this.form = this.buildForm();
if (this.data.selection) {
this.form.patchValue({
label: this.data.selection.toString()
});
}
}
buildForm() {
return this.formBuilder.group({
'label': [null, [Validators.required]],
'url': [null, [Validators.required]],
});
}
}
LinkDialogComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LinkDialogComponent, deps: [{ token: i1.FormBuilder }, { token: MAT_DIALOG_DATA }], target: i0.ɵɵFactoryTarget.Component });
LinkDialogComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: LinkDialogComponent, selector: "iget-editor-link-dialog", providers: [], ngImport: i0, template: "<h1 mat-dialog-title>Edit Link</h1>\n<div mat-dialog-content [formGroup]=\"form\">\n <mat-form-field floatLabel=\"always\">\n <input matInput placeholder=\"Label\" formControlName=\"label\">\n </mat-form-field>\n <mat-form-field floatLabel=\"always\">\n <input matInput placeholder=\"Web address or email\" formControlName=\"url\" cdkFocusInitial>\n </mat-form-field>\n</div>\n<div mat-dialog-actions>\n <button mat-button [mat-dialog-close]>Cancel</button>\n <button mat-button [disabled]=\"form.invalid\" [mat-dialog-close]=\"form.value\">OK</button>\n</div>\n", styles: ["[mat-dialog-content] mat-form-field{width:100%}\n"], components: [{ type: i2.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i4.MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { type: i4.MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i5.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i1.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i4.MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]" }, { type: i4.MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["type", "mat-dialog-close", "aria-label", "matDialogClose"], exportAs: ["matDialogClose"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: LinkDialogComponent, decorators: [{
type: Component,
args: [{ selector: 'iget-editor-link-dialog', providers: [], template: "<h1 mat-dialog-title>Edit Link</h1>\n<div mat-dialog-content [formGroup]=\"form\">\n <mat-form-field floatLabel=\"always\">\n <input matInput placeholder=\"Label\" formControlName=\"label\">\n </mat-form-field>\n <mat-form-field floatLabel=\"always\">\n <input matInput placeholder=\"Web address or email\" formControlName=\"url\" cdkFocusInitial>\n </mat-form-field>\n</div>\n<div mat-dialog-actions>\n <button mat-button [mat-dialog-close]>Cancel</button>\n <button mat-button [disabled]=\"form.invalid\" [mat-dialog-close]=\"form.value\">OK</button>\n</div>\n", styles: ["[mat-dialog-content] mat-form-field{width:100%}\n"] }]
}], ctorParameters: function () {
return [{ type: i1.FormBuilder }, { type: undefined, decorators: [{
type: Inject,
args: [MAT_DIALOG_DATA]
}] }];
} });
const COLOR_PALETTE = [
'#000000', '#444444', '#666666', '#999999', '#cccccc', '#eeeeee', '#f3f3f3', '#ffffff',
null,
'#ff0000', '#ff9900', '#ffff00', '#00ff00', '#00ffff', '#0000ff', '#9900ff', '#ff00ff',
null,
'#f4cccc', '#fce5cd', '#fff2cc', '#d9ead3', '#d0e0e3', '#cfe2f3', '#d9d2e9', '#ead1dc',
'#ea9999', '#f9cb9c', '#ffe599', '#b6d7a8', '#a2c4c9', '#9fc5e8', '#b4a7d6', '#d5a6bd',
'#e06666', '#f6b26b', '#ffd966', '#93c47d', '#76a5af', '#6fa8dc', '#8e7cc3', '#c27ba0',
'#cc0000', '#e69138', '#f1c232', '#6aa84f', '#45818e', '#3d85c6', '#674ea7', '#a64d79',
'#990000', '#b45f06', '#bf9000', '#38761d', '#134f5c', '#0b5394', '#351c75', '#741b47',
'#660000', '#783f04', '#7f6000', '#274e13', '#0c343d', '#073763', '#20124d', '#4c1130'
];
class IgetEditorToolbarGroupComponent {
}
IgetEditorToolbarGroupComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorToolbarGroupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
IgetEditorToolbarGroupComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: IgetEditorToolbarGroupComponent, selector: "iget-editor-toolbar-group", providers: [], ngImport: i0, template: "<ng-content select=\"ng-container, iget-editor-toolbar-button, mat-menu\"></ng-content>\n", styles: [":host{padding-left:4px;margin-bottom:2px}:host:not(:last-child){padding-right:4px;border-right:1px solid #e0e0e0}\n"] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorToolbarGroupComponent, decorators: [{
type: Component,
args: [{ selector: 'iget-editor-toolbar-group', providers: [], template: "<ng-content select=\"ng-container, iget-editor-toolbar-button, mat-menu\"></ng-content>\n", styles: [":host{padding-left:4px;margin-bottom:2px}:host:not(:last-child){padding-right:4px;border-right:1px solid #e0e0e0}\n"] }]
}] });
class IgetEditorToolbarButtonComponent {
constructor() {
this.menu = false;
this.clicked = new EventEmitter();
}
handleClick($event) {
this.clicked.emit($event);
$event.stopPropagation();
}
}
IgetEditorToolbarButtonComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorToolbarButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
IgetEditorToolbarButtonComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: IgetEditorToolbarButtonComponent, selector: "iget-editor-toolbar-button", inputs: { icon: "icon", title: "title", menu: "menu" }, outputs: { clicked: "clicked" }, providers: [], ngImport: i0, template: "<button mat-icon-button [title]=\"title\" (click)=\"handleClick($event)\" *ngIf=\"!menu\">\n <mat-icon>{{ icon }}</mat-icon>\n</button>\n<ng-container *ngIf=\"menu\">\n <button mat-icon-button [title]=\"title\" (click)=\"handleClick($event)\" *ngIf=\"menu\" [matMenuTriggerFor]=\"dropdown\">\n <mat-icon>{{ icon }}</mat-icon>\n </button>\n <mat-menu #dropdown=\"matMenu\">\n <ng-content select=\"[mat-menu-item],[matMenuContent]\"></ng-content>\n </mat-menu>\n</ng-container>\n", styles: ["button:focus{outline:none}button.mat-button{color:#616161}button.mat-button:hover{color:#212121}\n"], components: [{ type: i3.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i2$1.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i3$1.MatMenu, selector: "mat-menu", exportAs: ["matMenu"] }], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3$1.MatMenuTrigger, selector: "[mat-menu-trigger-for], [matMenuTriggerFor]", exportAs: ["matMenuTrigger"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorToolbarButtonComponent, decorators: [{
type: Component,
args: [{ selector: 'iget-editor-toolbar-button', providers: [], template: "<button mat-icon-button [title]=\"title\" (click)=\"handleClick($event)\" *ngIf=\"!menu\">\n <mat-icon>{{ icon }}</mat-icon>\n</button>\n<ng-container *ngIf=\"menu\">\n <button mat-icon-button [title]=\"title\" (click)=\"handleClick($event)\" *ngIf=\"menu\" [matMenuTriggerFor]=\"dropdown\">\n <mat-icon>{{ icon }}</mat-icon>\n </button>\n <mat-menu #dropdown=\"matMenu\">\n <ng-content select=\"[mat-menu-item],[matMenuContent]\"></ng-content>\n </mat-menu>\n</ng-container>\n", styles: ["button:focus{outline:none}button.mat-button{color:#616161}button.mat-button:hover{color:#212121}\n"] }]
}], propDecorators: { icon: [{
type: Input
}], title: [{
type: Input
}], menu: [{
type: Input
}], clicked: [{
type: Output
}] } });
class IgetEditorToolbarComponent {
constructor(_messageService, _commandExecutorService, dialog) {
this._messageService = _messageService;
this._commandExecutorService = _commandExecutorService;
this.dialog = dialog;
/** font family name */
this.fontName = '';
/** font size */
this.fontSize = '';
/**
* Emits an event when a toolbar button is clicked
*/
this.execute = new EventEmitter();
this.colors = COLOR_PALETTE;
}
/**
* enable or diable toolbar based on configuration
*
* @param value name of the toolbar buttons
*/
canEnableToolbarOptions(value) {
return canEnableToolbarOptions(value, this.config['toolbar']);
}
/**
* triggers command from the toolbar to be executed and emits an event
*
* @param command name of the command to be executed
*/
triggerCommand(command) {
this.execute.emit(command);
}
/**
* inserts link in the editor
*/
insertLink() {
const linkDialogRef = this.dialog.open(LinkDialogComponent, {
data: {
selection: this._commandExecutorService.savedSelection
}
});
linkDialogRef.afterClosed().subscribe((data) => {
if (data) {
let urlLink = data.url;
const emailPattern = new RegExp([
'^(([^<>()\\[\\]\\.,;:\\s@\\"]+(\\.[^<>()\\[\\]\\.,;:\\s@\\"]+)*)',
'|(\\".+\\"))@(([^<>()[\\]\\.,;:\\s@\\"]+\\.)+[^<>()[\\]\\.,;:\\s',
'@\\"]{2,})$'
].join(''));
if (emailPattern.exec(urlLink)) {
urlLink = `mailto:${urlLink}`;
}
this._commandExecutorService.createLink({
urlLink,
urlText: data.label,
});
}
});
}
/** insert text/background color */
setTextColor(color) {
this.insertColor(color, 'textColor');
}
/** insert text/background color */
setBackgroundColor(color) {
this.insertColor(color, 'backgroundColor');
}
/** insert text/background color */
insertColor(color, where) {
try {
this._commandExecutorService.insertColor(color, where);
}
catch (error) {
this._messageService.sendMessage(error.message);
}
}
/** set font size */
setFontSize(fontSize) {
try {
this._commandExecutorService.setFontSize(fontSize);
}
catch (error) {
this._messageService.sendMessage(error.message);
}
}
/** set font Name/family */
setFontName(fontName) {
try {
this._commandExecutorService.setFontName(fontName);
}
catch (error) {
this._messageService.sendMessage(error.message);
}
}
}
IgetEditorToolbarComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorToolbarComponent, deps: [{ token: MessageService }, { token: CommandExecutorService }, { token: i4.MatDialog }], target: i0.ɵɵFactoryTarget.Component });
IgetEditorToolbarComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: IgetEditorToolbarComponent, selector: "iget-editor-toolbar", inputs: { config: "config" }, outputs: { execute: "execute" }, providers: [], ngImport: i0, template: "<iget-editor-toolbar-group *ngFor=\"let group of config\">\n <ng-container *ngFor=\"let button of group\">\n <iget-editor-toolbar-button *ngIf=\"button === 'bold'\" icon=\"format_bold\" title=\"Bold\" (clicked)=\"triggerCommand('bold')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'italic'\" icon=\"format_italic\" title=\"Italic\" (clicked)=\"triggerCommand('italic')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'underline'\" icon=\"format_underline\" title=\"Underline\" (clicked)=\"triggerCommand('underline')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'strikethrough'\" icon=\"format_strikethrough\" title=\"Strikethrough\" (clicked)=\"triggerCommand('strikethrough')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'font'\" icon=\"font_download\" title=\"Font Family\" [menu]=\"true\">\n <button mat-menu-item (clicked)=\"setFontName('sans-serif')\" [style.fontFamily]=\"'sans-serif'\">Sans-serif</button>\n <button mat-menu-item (clicked)=\"setFontName('serif')\" [style.fontFamily]=\"'serif'\">Serif</button>\n <button mat-menu-item (clicked)=\"setFontName('monospace')\" [style.fontFamily]=\"'monospace'\">Monospace</button>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'fontSize'\" icon=\"format_size\" title=\"Font size\" [menu]=\"true\">\n <button mat-menu-item (clicked)=\"setFontSize('10')\" [style.fontSize]=\"'10px'\">Small</button>\n <button mat-menu-item (clicked)=\"setFontSize('13')\" [style.fontSize]=\"'13px'\">Regular</button>\n <button mat-menu-item (clicked)=\"setFontSize('18')\" [style.fontSize]=\"'18px'\">Large</button>\n <button mat-menu-item (clicked)=\"setFontSize('32')\" [style.fontSize]=\"'32px'\">Huge</button>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'textColor'\" icon=\"format_color_text\" title=\"Text color\" [menu]=\"true\">\n <div class=\"colors\" matMenuContent>\n <span *ngFor=\"let color of colors\" [style.backgroundColor]=\"color\" [class.separator]=\"!color\" (clicked)=\"setTextColor(color)\"></span>\n </div>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'fillColor'\" icon=\"format_color_fill\" title=\"Fill color\" [menu]=\"true\">\n <div class=\"colors\" matMenuContent>\n <span *ngFor=\"let color of colors\" [style.backgroundColor]=\"color\" [class.separator]=\"!color\" (clicked)=\"setBackgroundColor(color)\"></span>\n </div>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'removeFormat'\" icon=\"format_clear\" title=\"Clear formatting\" (clicked)=\"triggerCommand('removeFormat')\"></iget-editor-toolbar-button>\n <ng-container *ngIf=\"button === 'align'\">\n <iget-editor-toolbar-button icon=\"format_align_left\" title=\"Align left\" (clicked)=\"triggerCommand('justifyLeft')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_align_center\" title=\"Align center\" (clicked)=\"triggerCommand('justifyCenter')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_align_right\" title=\"Align right\" (clicked)=\"triggerCommand('justifyRight')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_align_justify\" title=\"Justify\" (clicked)=\"triggerCommand('justifyFull')\"></iget-editor-toolbar-button>\n </ng-container>\n <ng-container *ngIf=\"button === 'indent'\">\n <iget-editor-toolbar-button icon=\"format_indent_decrease\" title=\"Outdent\" (clicked)=\"triggerCommand('outdent')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_indent_increase\" title=\"Indent\" (clicked)=\"triggerCommand('indent')\"></iget-editor-toolbar-button>\n </ng-container>\n <iget-editor-toolbar-button *ngIf=\"button === 'quote'\" icon=\"format_quote\" title=\"Blockquote\" (clicked)=\"triggerCommand('blockquote')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'unorderedList'\" icon=\"format_list_bulleted\" title=\"Unordered list\" (clicked)=\"triggerCommand('insertUnorderedList')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'orderedList'\" icon=\"format_list_numbered\" title=\"Ordered list\" (clicked)=\"triggerCommand('insertOrderedList')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'undo'\" icon=\"undo\" title=\"Undo\" (clicked)=\"triggerCommand('undo')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'redo'\" icon=\"redo\" title=\"Redo\" (clicked)=\"triggerCommand('redo')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'anchor'\" icon=\"insert_link\" title=\"Insert link\" (clicked)=\"insertLink()\"></iget-editor-toolbar-button>\n </ng-container>\n", styles: [":host{display:flex;flex-wrap:wrap;box-shadow:0 3px 1px -2px #0003,0 2px 2px #00000024,0 1px 5px #0000001f}.mat-button{padding:0;min-width:36px}.colors{display:flex;flex-wrap:wrap;width:180px;margin:0 8px}.colors>span:not(.separator){width:calc(12.5% - 2px);display:block;height:auto;padding-top:calc(12.5% - 2px);cursor:pointer;border:1px solid white}.colors>span:not(.separator):hover{border-color:#000}.colors>span.separator{width:100%;height:4px}\n"], components: [{ type: IgetEditorToolbarGroupComponent, selector: "iget-editor-toolbar-group" }, { type: IgetEditorToolbarButtonComponent, selector: "iget-editor-toolbar-button", inputs: ["icon", "title", "menu"], outputs: ["clicked"] }, { type: i3$1.MatMenuItem, selector: "[mat-menu-item]", inputs: ["disabled", "disableRipple", "role"], exportAs: ["matMenuItem"] }], directives: [{ type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorToolbarComponent, decorators: [{
type: Component,
args: [{ selector: 'iget-editor-toolbar', providers: [], template: "<iget-editor-toolbar-group *ngFor=\"let group of config\">\n <ng-container *ngFor=\"let button of group\">\n <iget-editor-toolbar-button *ngIf=\"button === 'bold'\" icon=\"format_bold\" title=\"Bold\" (clicked)=\"triggerCommand('bold')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'italic'\" icon=\"format_italic\" title=\"Italic\" (clicked)=\"triggerCommand('italic')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'underline'\" icon=\"format_underline\" title=\"Underline\" (clicked)=\"triggerCommand('underline')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'strikethrough'\" icon=\"format_strikethrough\" title=\"Strikethrough\" (clicked)=\"triggerCommand('strikethrough')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'font'\" icon=\"font_download\" title=\"Font Family\" [menu]=\"true\">\n <button mat-menu-item (clicked)=\"setFontName('sans-serif')\" [style.fontFamily]=\"'sans-serif'\">Sans-serif</button>\n <button mat-menu-item (clicked)=\"setFontName('serif')\" [style.fontFamily]=\"'serif'\">Serif</button>\n <button mat-menu-item (clicked)=\"setFontName('monospace')\" [style.fontFamily]=\"'monospace'\">Monospace</button>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'fontSize'\" icon=\"format_size\" title=\"Font size\" [menu]=\"true\">\n <button mat-menu-item (clicked)=\"setFontSize('10')\" [style.fontSize]=\"'10px'\">Small</button>\n <button mat-menu-item (clicked)=\"setFontSize('13')\" [style.fontSize]=\"'13px'\">Regular</button>\n <button mat-menu-item (clicked)=\"setFontSize('18')\" [style.fontSize]=\"'18px'\">Large</button>\n <button mat-menu-item (clicked)=\"setFontSize('32')\" [style.fontSize]=\"'32px'\">Huge</button>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'textColor'\" icon=\"format_color_text\" title=\"Text color\" [menu]=\"true\">\n <div class=\"colors\" matMenuContent>\n <span *ngFor=\"let color of colors\" [style.backgroundColor]=\"color\" [class.separator]=\"!color\" (clicked)=\"setTextColor(color)\"></span>\n </div>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'fillColor'\" icon=\"format_color_fill\" title=\"Fill color\" [menu]=\"true\">\n <div class=\"colors\" matMenuContent>\n <span *ngFor=\"let color of colors\" [style.backgroundColor]=\"color\" [class.separator]=\"!color\" (clicked)=\"setBackgroundColor(color)\"></span>\n </div>\n </iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'removeFormat'\" icon=\"format_clear\" title=\"Clear formatting\" (clicked)=\"triggerCommand('removeFormat')\"></iget-editor-toolbar-button>\n <ng-container *ngIf=\"button === 'align'\">\n <iget-editor-toolbar-button icon=\"format_align_left\" title=\"Align left\" (clicked)=\"triggerCommand('justifyLeft')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_align_center\" title=\"Align center\" (clicked)=\"triggerCommand('justifyCenter')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_align_right\" title=\"Align right\" (clicked)=\"triggerCommand('justifyRight')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_align_justify\" title=\"Justify\" (clicked)=\"triggerCommand('justifyFull')\"></iget-editor-toolbar-button>\n </ng-container>\n <ng-container *ngIf=\"button === 'indent'\">\n <iget-editor-toolbar-button icon=\"format_indent_decrease\" title=\"Outdent\" (clicked)=\"triggerCommand('outdent')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button icon=\"format_indent_increase\" title=\"Indent\" (clicked)=\"triggerCommand('indent')\"></iget-editor-toolbar-button>\n </ng-container>\n <iget-editor-toolbar-button *ngIf=\"button === 'quote'\" icon=\"format_quote\" title=\"Blockquote\" (clicked)=\"triggerCommand('blockquote')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'unorderedList'\" icon=\"format_list_bulleted\" title=\"Unordered list\" (clicked)=\"triggerCommand('insertUnorderedList')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'orderedList'\" icon=\"format_list_numbered\" title=\"Ordered list\" (clicked)=\"triggerCommand('insertOrderedList')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'undo'\" icon=\"undo\" title=\"Undo\" (clicked)=\"triggerCommand('undo')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'redo'\" icon=\"redo\" title=\"Redo\" (clicked)=\"triggerCommand('redo')\"></iget-editor-toolbar-button>\n <iget-editor-toolbar-button *ngIf=\"button === 'anchor'\" icon=\"insert_link\" title=\"Insert link\" (clicked)=\"insertLink()\"></iget-editor-toolbar-button>\n </ng-container>\n", styles: [":host{display:flex;flex-wrap:wrap;box-shadow:0 3px 1px -2px #0003,0 2px 2px #00000024,0 1px 5px #0000001f}.mat-button{padding:0;min-width:36px}.colors{display:flex;flex-wrap:wrap;width:180px;margin:0 8px}.colors>span:not(.separator){width:calc(12.5% - 2px);display:block;height:auto;padding-top:calc(12.5% - 2px);cursor:pointer;border:1px solid white}.colors>span:not(.separator):hover{border-color:#000}.colors>span.separator{width:100%;height:4px}\n"] }]
}], ctorParameters: function () { return [{ type: MessageService }, { type: CommandExecutorService }, { type: i4.MatDialog }]; }, propDecorators: { config: [{
type: Input
}], execute: [{
type: Output
}] } });
class IgetEditorMessageComponent {
/**
* @param _messageService service to send message to the editor
*/
constructor(_messageService) {
this._messageService = _messageService;
/** property that holds the message to be displayed on the editor */
this.ngxMessage = undefined;
this._messageService.getMessage().subscribe((message) => this.ngxMessage = message);
}
/**
* clears editor message
*/
clearMessage() {
this.ngxMessage = undefined;
}
}
IgetEditorMessageComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorMessageComponent, deps: [{ token: MessageService }], target: i0.ɵɵFactoryTarget.Component });
IgetEditorMessageComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: IgetEditorMessageComponent, selector: "iget-editor-message", ngImport: i0, template: "<div class=\"iget-editor-message\" *ngIf=\"ngxMessage\" (dblclick)=\"clearMessage()\">\n {{ ngxMessage }}\n</div>\n", styles: [".iget-editor-message{font-size:80%;background-color:#f1f1f1;border:1px solid #ddd;border-top:transparent;padding:0 .5rem .1rem;transition:.5s ease-in}\n"], directives: [{ type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorMessageComponent, decorators: [{
type: Component,
args: [{ selector: 'iget-editor-message', template: "<div class=\"iget-editor-message\" *ngIf=\"ngxMessage\" (dblclick)=\"clearMessage()\">\n {{ ngxMessage }}\n</div>\n", styles: [".iget-editor-message{font-size:80%;background-color:#f1f1f1;border:1px solid #ddd;border-top:transparent;padding:0 .5rem .1rem;transition:.5s ease-in}\n"] }]
}], ctorParameters: function () { return [{ type: MessageService }]; } });
class IgetEditorGrippieComponent {
/**
* Constructor
*/
constructor() {
/** previous value befor resizing the editor */
this.oldY = 0;
/** set to true on mousedown event */
this.grabber = false;
this.resized = new EventEmitter();
}
/**
*
* @param event Mouseevent
*
* Update the height of the editor when the grabber is dragged
*/
onMouseMove(event) {
if (!this.grabber) {
return;
}
this.resized.emit(event.clientY - this.oldY);
this.oldY = event.clientY;
}
/**
*
* @param event Mouseevent
*
* set the grabber to false on mouse up action
*/
onMouseUp(event) {
this.grabber = false;
}
onResize(event, resizer) {
this.grabber = true;
this.oldY = event.clientY;
event.preventDefault();
}
}
IgetEditorGrippieComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorGrippieComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
IgetEditorGrippieComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.1", type: IgetEditorGrippieComponent, selector: "iget-editor-grippie", outputs: { resized: "resized" }, host: { listeners: { "document:mousemove": "onMouseMove($event)", "document:mouseup": "onMouseUp($event)", "mousedown": "onResize($event)" } }, ngImport: i0, template: "<div class=\"iget-editor-grippie\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" style=\"isolation:isolate\" viewBox=\"651.6 235 26 5\"\n width=\"26\" height=\"5\">\n <g id=\"sprites\">\n <path d=\" M 651.6 235 L 653.6 235 L 653.6 237 L 651.6 237 M 654.6 238 L 656.6 238 L 656.6 240 L 654.6 240 M 660.6 238 L 662.6 238 L 662.6 240 L 660.6 240 M 666.6 238 L 668.6 238 L 668.6 240 L 666.6 240 M 672.6 238 L 674.6 238 L 674.6 240 L 672.6 240 M 657.6 235 L 659.6 235 L 659.6 237 L 657.6 237 M 663.6 235 L 665.6 235 L 665.6 237 L 663.6 237 M 669.6 235 L 671.6 235 L 671.6 237 L 669.6 237 M 675.6 235 L 677.6 235 L 677.6 237 L 675.6 237\"\n fill=\"rgb(147,153,159)\" />\n </g>\n </svg>\n</div>\n", styles: [".iget-editor-grippie{height:9px;position:relative;text-align:center;cursor:s-resize}.iget-editor-grippie svg{position:absolute;top:1.5px;width:50%;right:25%}\n"] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.1", ngImport: i0, type: IgetEditorGrippieComponent, decorators: [{
type: Component,
args: [{ selector: 'iget-editor-grippie', template: "<div class=\"iget-editor-grippie\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" style=\"isolation:isolate\" viewBox=\"651.6 235 26 5\"\n width=\"26\" height=\"5\">\n <g id=\"sprites\">\n <path d=\" M 651.6 235 L 653.6 235 L 653.6 237 L 651.6 237 M 654.6 238 L 656.6 238 L 656.6 240 L 654.6 240 M 660.6 238 L 662.6 238 L 662.6 240 L 660.6 240 M 666.6 238 L 668.6 238 L 668.6 240 L 666.6 240 M 672.6 238 L 674.6 238 L 674.6 240 L 672.6 240 M 657.6 235 L 659.6 235 L 659.6 237 L 657.6 237 M 663.6 235 L 665.6 235 L 665.6 237 L 663.6 237 M 669.6 235 L 671.6 235 L 671.6 237 L 669.6 237 M 675.6 235 L 677.6 235 L 677.6 237 L 675.6 237\"\n fill=\"rgb(147,153,159)\" />\n </g>\n </svg>\n</div>\n", styles: [".iget-editor-grippie{height:9px;position:relative;text-align:center;cursor:s-resize}.iget-editor-grippie svg{position:absolute;top:1.5px;width:50%;right:25%}\n"] }]
}], ctorParameters: function () { return []; }, propDecorators: { resized: [{
type: Output
}], onMouseMove: [{
type: HostListener,
args: ['document:mousemove', ['$event']]
}], onMouseUp: [{
type: HostListener,
args: ['document:mouseup', ['$event']]
}], onResize: [{
type: HostListener,
args: ['mousedown', ['$event']]
}] } });
class IgetEditorComponent {
/**
* @param sanitizer Dom Sanitizer
* @param _messageService service to send message to the editor message component
* @param _commandExecutor executes command from the toolbar
* @param _renderer access and manipulate the dom element
*/
constructor(sanitizer, _messageService, _commandExecutor, _renderer) {
this.sanitizer = sanitizer;
this._messageService = _messageService;
this._commandExecutor = _commandExecutor;
this._renderer = _renderer;
/** emits `blured` event when focused out from the textarea */
this.blured = new EventEmitter();
/** emits `focused` event when focused in to the textarea */
this.focused = new EventEmitter();
this.Utils = Utils;
this.showPlaceholder = true;
}
/**
* events
*/
onTextAreaFocus() {
this.focused.emit('focus');
}
/** focus the text area when the editor is focussed */
onEditorFocus() {
this.textArea.nativeElement.focus();
}
/**
* Executed from the contenteditable section while the input property changes
*/
onContentChange($event) {
const innerHtml = $event.target.innerHTML;
if (typeof this.onChange === 'function') {
this.onChange(innerHtml);
this.togglePlaceholder(innerHtml);
}
}
onTextAreaBlur() {
/** save selection if focussed out */
this._commandExecutor.savedSelection = saveSelection();
if (typeof this.onTouched === 'function') {
this.onTouched();
}
this.blured.emit('blur');
}
/**
* resizing text area
*
* @param offsetY vertical height of the editable portion of the editor
*/
resizeTextArea(offsetY) {
const oldHeight = parseInt(getComputedStyle(this.textArea.nativeElement).height, 10);
this.textArea.nativeElement.style.height = (oldHeight + offsetY) + 'px';
}
/**
* editor actions, i.e., executes command from toolbar
*
* @param commandName name of the command to be executed
*/
executeCommand(commandName) {
try {
this._commandExecutor.execute(commandName);
}
catch (error) {
this._messageService.sendMessage(error.message);
}
}
/**
* Write a new value to the element.
*
* @param value value to be executed when there is a change in contenteditable
*/
writeValue(value) {
this.togglePlaceholder(value);
if (value === null || value === undefined || value === '' || value === '<br>') {
value = null;
}
this.value = this.sanitizer.bypassSecurityTrustHtml(value);
}
/**
* Set the function to be called
* when the control receives a change event.
*
* @param fn a function
*/
registerOnChange(fn) {
this.onChange = fn;
}
/**
* Set the function to be called
* when the control receives a touch event.
*
* @param fn a function
*/
registerOnTouched(fn) {
this.onTouched = fn;
}
/**
* toggles placeholder based on input string
*
* @param value A HTML string from the editor
*/
togglePlaceholder(value) {
if (!value || value === '<br>' || value === '') {
this.showPlaceholder = true;
}
else {
this.showPlaceholder = false;
}
}
ngOnInit() {
// this.height = this.height || this.textArea.nativeElement.offsetHeight;