diff --git a/projects/angular-editor-app/src/app/app.component.html b/projects/angular-editor-app/src/app/app.component.html
index 407596cc0..1f315f218 100644
--- a/projects/angular-editor-app/src/app/app.component.html
+++ b/projects/angular-editor-app/src/app/app.component.html
@@ -5,7 +5,7 @@
Angular Editor
-
HTML Output: {{ htmlContent1 }}
@@ -19,5 +19,6 @@
Angular Editor
Form Status: {{ form.status }}
+ Insert at cursor
diff --git a/projects/angular-editor-app/src/app/app.component.ts b/projects/angular-editor-app/src/app/app.component.ts
index f42001d55..5582df6b0 100644
--- a/projects/angular-editor-app/src/app/app.component.ts
+++ b/projects/angular-editor-app/src/app/app.component.ts
@@ -1,102 +1,109 @@
-import {Component, OnInit} from '@angular/core';
-import {AngularEditorConfig} from 'angular-editor';
-import {FormBuilder, FormGroup, Validators} from '@angular/forms';
-
+import { Component, OnInit, ViewChild } from "@angular/core";
+import { FormBuilder, FormGroup, Validators } from "@angular/forms";
+import { AngularEditorConfig } from "angular-editor";
+import { AngularEditorComponent } from "projects/angular-editor/src/public-api";
@Component({
- selector: 'app-root',
- templateUrl: './app.component.html',
- styleUrls: ['./app.component.scss']
+ selector: "app-root",
+ templateUrl: "./app.component.html",
+ styleUrls: ["./app.component.scss"],
})
export class AppComponent implements OnInit {
- title = 'app';
+ title = "app";
+ @ViewChild("editorRef") editorRef: AngularEditorComponent;
form: FormGroup;
- htmlContent1 = '';
- htmlContent2 = '';
+ htmlContent1 = "";
+ htmlContent2 = "";
config1: AngularEditorConfig = {
editable: true,
spellcheck: true,
- minHeight: '5rem',
- maxHeight: '15rem',
- placeholder: 'Enter text here...',
- translate: 'no',
+ minHeight: "5rem",
+ maxHeight: "15rem",
+ placeholder: "Enter text here...",
+ translate: "no",
sanitize: false,
// toolbarPosition: 'top',
outline: true,
- defaultFontName: 'Comic Sans MS',
- defaultFontSize: '5',
+ defaultFontName: "Comic Sans MS",
+ defaultFontSize: "5",
// showToolbar: false,
- defaultParagraphSeparator: 'p',
+ defaultParagraphSeparator: "p",
customClasses: [
{
- name: 'quote',
- class: 'quote',
+ name: "quote",
+ class: "quote",
},
{
- name: 'redText',
- class: 'redText'
+ name: "redText",
+ class: "redText",
},
{
- name: 'titleText',
- class: 'titleText',
- tag: 'h1',
+ name: "titleText",
+ class: "titleText",
+ tag: "h1",
},
],
- toolbarHiddenButtons: [
- ['bold', 'italic'],
- ['fontSize']
- ]
+ toolbarHiddenButtons: [["bold", "italic"], ["fontSize"]],
};
config2: AngularEditorConfig = {
editable: true,
spellcheck: true,
- minHeight: '5rem',
- maxHeight: '15rem',
- placeholder: 'Enter text here...',
- translate: 'no',
+ minHeight: "5rem",
+ maxHeight: "15rem",
+ placeholder: "Enter text here...",
+ translate: "no",
sanitize: true,
- toolbarPosition: 'bottom',
- defaultFontName: 'Comic Sans MS',
- defaultFontSize: '5',
- defaultParagraphSeparator: 'p',
+ toolbarPosition: "bottom",
+ defaultFontName: "Comic Sans MS",
+ defaultFontSize: "5",
+ defaultParagraphSeparator: "p",
customClasses: [
{
- name: 'quote',
- class: 'quote',
+ name: "quote",
+ class: "quote",
},
{
- name: 'redText',
- class: 'redText'
+ name: "redText",
+ class: "redText",
},
{
- name: 'titleText',
- class: 'titleText',
- tag: 'h1',
+ name: "titleText",
+ class: "titleText",
+ tag: "h1",
},
- ]
+ ],
};
constructor(private formBuilder: FormBuilder) {}
ngOnInit() {
this.form = this.formBuilder.group({
- signature: ['', Validators.required]
+ signature: ["", Validators.required],
});
console.log(this.htmlContent1);
}
onChange(event) {
- console.log('changed');
+ console.log("changed");
}
onBlur(event) {
- console.log('blur ' + event);
+ console.log("blur " + event);
}
onChange2(event) {
console.warn(this.form.value);
}
+ cnt = 0;
+ insertTextAtCursor() {
+ this.editorRef.insertTextAtCursor(`{${this.cnt}}`);
+ this.cnt++;
+ }
+ onTextAreaMouseOut(event) {
+ console.log(`onTextAreaMouseOut`);
+ console.log(event);
+ }
}
diff --git a/projects/angular-editor/src/lib/angular-editor.component.ts b/projects/angular-editor/src/lib/angular-editor.component.ts
index 2d4132615..f3490b8e4 100644
--- a/projects/angular-editor/src/lib/angular-editor.component.ts
+++ b/projects/angular-editor/src/lib/angular-editor.component.ts
@@ -15,31 +15,31 @@ import {
Output,
Renderer2,
SecurityContext,
- ViewChild
-} from '@angular/core';
-import {ControlValueAccessor, NG_VALUE_ACCESSOR} from '@angular/forms';
-import {AngularEditorConfig, angularEditorConfig} from './config';
-import {AngularEditorToolbarComponent} from './angular-editor-toolbar.component';
-import {AngularEditorService} from './angular-editor.service';
-import {DOCUMENT} from '@angular/common';
-import {DomSanitizer} from '@angular/platform-browser';
-import {isDefined} from './utils';
+ ViewChild,
+} from "@angular/core";
+import { ControlValueAccessor, NG_VALUE_ACCESSOR } from "@angular/forms";
+import { AngularEditorConfig, angularEditorConfig } from "./config";
+import { AngularEditorToolbarComponent } from "./angular-editor-toolbar.component";
+import { AngularEditorService } from "./angular-editor.service";
+import { DOCUMENT } from "@angular/common";
+import { DomSanitizer } from "@angular/platform-browser";
+import { isDefined } from "./utils";
@Component({
- selector: 'angular-editor',
- templateUrl: './angular-editor.component.html',
- styleUrls: ['./angular-editor.component.scss'],
+ selector: "angular-editor",
+ templateUrl: "./angular-editor.component.html",
+ styleUrls: ["./angular-editor.component.scss"],
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => AngularEditorComponent),
- multi: true
+ multi: true,
},
- AngularEditorService
- ]
+ AngularEditorService,
+ ],
})
-export class AngularEditorComponent implements OnInit, ControlValueAccessor, AfterViewInit, OnDestroy {
-
+export class AngularEditorComponent
+ implements OnInit, ControlValueAccessor, AfterViewInit, OnDestroy {
private onChange: (value: string) => void;
private onTouched: () => void;
@@ -52,31 +52,33 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
focusInstance: any;
blurInstance: any;
-
- @Input() id = '';
+ currentCursorSelection: Range;
+ @Input() id = "";
@Input() config: AngularEditorConfig = angularEditorConfig;
- @Input() placeholder = '';
+ @Input() placeholder = "";
@Input() tabIndex: number | null;
@Output() html;
- @ViewChild('editor', {static: true}) textArea: ElementRef;
- @ViewChild('editorWrapper', {static: true}) editorWrapper: ElementRef;
- @ViewChild('editorToolbar') editorToolbar: AngularEditorToolbarComponent;
+ @ViewChild("editor", { static: true }) textArea: ElementRef;
+ @ViewChild("editorWrapper", { static: true }) editorWrapper: ElementRef;
+ @ViewChild("editorToolbar") editorToolbar: AngularEditorToolbarComponent;
@Output() viewMode = new EventEmitter();
/** emits `blur` event when focused out from the textarea */
- // tslint:disable-next-line:no-output-native no-output-rename
- @Output('blur') blurEvent: EventEmitter = new EventEmitter();
+ // tslint:disable-next-line:no-output-native no-output-rename
+ @Output("blur")
+ blurEvent: EventEmitter = new EventEmitter();
/** emits `focus` event when focused in to the textarea */
- // tslint:disable-next-line:no-output-rename no-output-native
- @Output('focus') focusEvent: EventEmitter = new EventEmitter();
+ // tslint:disable-next-line:no-output-rename no-output-native
+ @Output("focus")
+ focusEvent: EventEmitter = new EventEmitter();
- @HostBinding('attr.tabindex') tabindex = -1;
+ @HostBinding("attr.tabindex") tabindex = -1;
- @HostListener('focus')
+ @HostListener("focus")
onFocus() {
this.focus();
}
@@ -87,15 +89,18 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
@Inject(DOCUMENT) private doc: any,
private sanitizer: DomSanitizer,
private cdRef: ChangeDetectorRef,
- @Attribute('tabindex') defaultTabIndex: string,
- @Attribute('autofocus') private autoFocus: any
+ @Attribute("tabindex") defaultTabIndex: string,
+ @Attribute("autofocus") private autoFocus: any
) {
const parsedTabIndex = Number(defaultTabIndex);
- this.tabIndex = (parsedTabIndex || parsedTabIndex === 0) ? parsedTabIndex : null;
+ this.tabIndex =
+ parsedTabIndex || parsedTabIndex === 0 ? parsedTabIndex : null;
}
ngOnInit() {
- this.config.toolbarPosition = this.config.toolbarPosition ? this.config.toolbarPosition : angularEditorConfig.toolbarPosition;
+ this.config.toolbarPosition = this.config.toolbarPosition
+ ? this.config.toolbarPosition
+ : angularEditorConfig.toolbarPosition;
}
ngAfterViewInit() {
@@ -110,17 +115,17 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
*/
executeCommand(command: string) {
this.focus();
- if (command === 'focus') {
+ if (command === "focus") {
return;
}
- if (command === 'toggleEditorMode') {
+ if (command === "toggleEditorMode") {
this.toggleEditorMode(this.modeVisual);
- } else if (command !== '') {
- if (command === 'clear') {
+ } else if (command !== "") {
+ if (command === "clear") {
this.editorService.removeSelectedElements(this.getCustomTags());
this.onContentChange(this.textArea.nativeElement);
- } else if (command === 'default') {
- this.editorService.removeSelectedElements('h1,h2,h3,h4,h5,h6,p,pre');
+ } else if (command === "default") {
+ this.editorService.removeSelectedElements("h1,h2,h3,h4,h5,h6,p,pre");
this.onContentChange(this.textArea.nativeElement);
} else {
this.editorService.executeCommand(command);
@@ -152,6 +157,7 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
*/
public onTextAreaMouseOut(event: MouseEvent): void {
this.editorService.saveSelection();
+ this.currentCursorSelection = this.editorService.savedSelection;
}
/**
@@ -161,15 +167,20 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
/**
* save selection if focussed out
*/
- this.editorService.executeInNextQueueIteration(this.editorService.saveSelection);
+ this.editorService.executeInNextQueueIteration(
+ this.editorService.saveSelection
+ );
- if (typeof this.onTouched === 'function') {
+ if (typeof this.onTouched === "function") {
this.onTouched();
}
if (event.relatedTarget !== null) {
const parent = (event.relatedTarget as HTMLElement).parentElement;
- if (!parent.classList.contains('angular-editor-toolbar-set') && !parent.classList.contains('ae-picker')) {
+ if (
+ !parent.classList.contains("angular-editor-toolbar-set") &&
+ !parent.classList.contains("ae-picker")
+ ) {
this.blurEvent.emit(event);
this.focused = false;
}
@@ -183,7 +194,7 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
if (this.modeVisual) {
this.textArea.nativeElement.focus();
} else {
- const sourceText = this.doc.getElementById('sourceText' + this.id);
+ const sourceText = this.doc.getElementById("sourceText" + this.id);
sourceText.focus();
this.focused = true;
}
@@ -194,19 +205,22 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
* @param element html element from contenteditable
*/
onContentChange(element: HTMLElement): void {
- let html = '';
+ let html = "";
if (this.modeVisual) {
html = element.innerHTML;
} else {
html = element.innerText;
}
- if ((!html || html === '
')) {
- html = '';
+ if (!html || html === "
") {
+ html = "";
}
- if (typeof this.onChange === 'function') {
- this.onChange(this.config.sanitize || this.config.sanitize === undefined ?
- this.sanitizer.sanitize(SecurityContext.HTML, html) : html);
- if ((!html) !== this.showPlaceholder) {
+ if (typeof this.onChange === "function") {
+ this.onChange(
+ this.config.sanitize || this.config.sanitize === undefined
+ ? this.sanitizer.sanitize(SecurityContext.HTML, html)
+ : html
+ );
+ if (!html !== this.showPlaceholder) {
this.togglePlaceholder(this.showPlaceholder);
}
}
@@ -220,7 +234,7 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
* @param fn a function
*/
registerOnChange(fn: any): void {
- this.onChange = e => (e === '
' ? fn('') : fn(e)) ;
+ this.onChange = (e) => (e === "
" ? fn("") : fn(e));
}
/**
@@ -239,12 +253,11 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
* @param value value to be executed when there is a change in contenteditable
*/
writeValue(value: any): void {
-
- if ((!value || value === '
' || value === '') !== this.showPlaceholder) {
+ if ((!value || value === "
" || value === "") !== this.showPlaceholder) {
this.togglePlaceholder(this.showPlaceholder);
}
- if (value === undefined || value === '' || value === '
') {
+ if (value === undefined || value === "" || value === "
") {
value = null;
}
@@ -257,8 +270,12 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
* @param value html string from the editor
*/
refreshView(value: string): void {
- const normalizedValue = value === null ? '' : value;
- this.r.setProperty(this.textArea.nativeElement, 'innerHTML', normalizedValue);
+ const normalizedValue = value === null ? "" : value;
+ this.r.setProperty(
+ this.textArea.nativeElement,
+ "innerHTML",
+ normalizedValue
+ );
return;
}
@@ -270,11 +287,10 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
*/
togglePlaceholder(value: boolean): void {
if (!value) {
- this.r.addClass(this.editorWrapper.nativeElement, 'show-placeholder');
+ this.r.addClass(this.editorWrapper.nativeElement, "show-placeholder");
this.showPlaceholder = true;
-
} else {
- this.r.removeClass(this.editorWrapper.nativeElement, 'show-placeholder');
+ this.r.removeClass(this.editorWrapper.nativeElement, "show-placeholder");
this.showPlaceholder = false;
}
}
@@ -286,8 +302,8 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
*/
setDisabledState(isDisabled: boolean): void {
const div = this.textArea.nativeElement;
- const action = isDisabled ? 'addClass' : 'removeClass';
- this.r[action](div, 'disabled');
+ const action = isDisabled ? "addClass" : "removeClass";
+ this.r[action](div, "disabled");
this.disabled = isDisabled;
}
@@ -302,43 +318,51 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
if (bToSource) {
oContent = this.r.createText(editableElement.innerHTML);
- this.r.setProperty(editableElement, 'innerHTML', '');
- this.r.setProperty(editableElement, 'contentEditable', false);
-
- const oPre = this.r.createElement('pre');
- this.r.setStyle(oPre, 'margin', '0');
- this.r.setStyle(oPre, 'outline', 'none');
-
- const oCode = this.r.createElement('code');
- this.r.setProperty(oCode, 'id', 'sourceText' + this.id);
- this.r.setStyle(oCode, 'display', 'block');
- this.r.setStyle(oCode, 'white-space', 'pre-wrap');
- this.r.setStyle(oCode, 'word-break', 'keep-all');
- this.r.setStyle(oCode, 'outline', 'none');
- this.r.setStyle(oCode, 'margin', '0');
- this.r.setStyle(oCode, 'background-color', '#fff5b9');
- this.r.setProperty(oCode, 'contentEditable', true);
+ this.r.setProperty(editableElement, "innerHTML", "");
+ this.r.setProperty(editableElement, "contentEditable", false);
+
+ const oPre = this.r.createElement("pre");
+ this.r.setStyle(oPre, "margin", "0");
+ this.r.setStyle(oPre, "outline", "none");
+
+ const oCode = this.r.createElement("code");
+ this.r.setProperty(oCode, "id", "sourceText" + this.id);
+ this.r.setStyle(oCode, "display", "block");
+ this.r.setStyle(oCode, "white-space", "pre-wrap");
+ this.r.setStyle(oCode, "word-break", "keep-all");
+ this.r.setStyle(oCode, "outline", "none");
+ this.r.setStyle(oCode, "margin", "0");
+ this.r.setStyle(oCode, "background-color", "#fff5b9");
+ this.r.setProperty(oCode, "contentEditable", true);
this.r.appendChild(oCode, oContent);
- this.focusInstance = this.r.listen(oCode, 'focus', (event) => this.onTextAreaFocus(event));
- this.blurInstance = this.r.listen(oCode, 'blur', (event) => this.onTextAreaBlur(event));
+ this.focusInstance = this.r.listen(oCode, "focus", (event) =>
+ this.onTextAreaFocus(event)
+ );
+ this.blurInstance = this.r.listen(oCode, "blur", (event) =>
+ this.onTextAreaBlur(event)
+ );
this.r.appendChild(oPre, oCode);
this.r.appendChild(editableElement, oPre);
// ToDo move to service
- this.doc.execCommand('defaultParagraphSeparator', false, 'div');
+ this.doc.execCommand("defaultParagraphSeparator", false, "div");
this.modeVisual = false;
this.viewMode.emit(false);
oCode.focus();
} else {
if (this.doc.querySelectorAll) {
- this.r.setProperty(editableElement, 'innerHTML', editableElement.innerText);
+ this.r.setProperty(
+ editableElement,
+ "innerHTML",
+ editableElement.innerText
+ );
} else {
oContent = this.doc.createRange();
oContent.selectNodeContents(editableElement.firstChild);
- this.r.setProperty(editableElement, 'innerHTML', oContent.toString());
+ this.r.setProperty(editableElement, "innerHTML", oContent.toString());
}
- this.r.setProperty(editableElement, 'contentEditable', true);
+ this.r.setProperty(editableElement, "contentEditable", true);
this.modeVisual = true;
this.viewMode.emit(true);
this.onContentChange(editableElement);
@@ -358,23 +382,26 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
let userSelection;
if (this.doc.getSelection) {
userSelection = this.doc.getSelection();
- this.editorService.executeInNextQueueIteration(this.editorService.saveSelection);
+ this.editorService.executeInNextQueueIteration(
+ this.editorService.saveSelection
+ );
}
let a = userSelection.focusNode;
const els = [];
- while (a && a.id !== 'editor') {
+ while (a && a.id !== "editor") {
els.unshift(a);
a = a.parentNode;
}
this.editorToolbar.triggerBlocks(els);
}
-
private configure() {
this.editorService.uploadUrl = this.config.uploadUrl;
this.editorService.uploadWithCredentials = this.config.uploadWithCredentials;
if (this.config.defaultParagraphSeparator) {
- this.editorService.setDefaultParagraphSeparator(this.config.defaultParagraphSeparator);
+ this.editorService.setDefaultParagraphSeparator(
+ this.config.defaultParagraphSeparator
+ );
}
if (this.config.defaultFontName) {
this.editorService.setFontName(this.config.defaultFontName);
@@ -385,22 +412,32 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
}
getFonts() {
- const fonts = this.config.fonts ? this.config.fonts : angularEditorConfig.fonts;
- return fonts.map(x => {
- return {label: x.name, value: x.name};
+ const fonts = this.config.fonts
+ ? this.config.fonts
+ : angularEditorConfig.fonts;
+ return fonts.map((x) => {
+ return { label: x.name, value: x.name };
});
}
getCustomTags() {
- const tags = ['span'];
- this.config.customClasses.forEach(x => {
+ const tags = ["span"];
+ this.config.customClasses.forEach((x) => {
if (x.tag !== undefined) {
if (!tags.includes(x.tag)) {
tags.push(x.tag);
}
}
});
- return tags.join(',');
+ return tags.join(",");
+ }
+ insertTextAtCursor(text: string) {
+ let selection = window.getSelection();
+ selection.removeAllRanges();
+ selection.addRange(this.currentCursorSelection);
+ this.editorService.insertHtml(text);
+ this.editorService.saveSelection();
+ this.currentCursorSelection = this.editorService.savedSelection;
}
ngOnDestroy() {
@@ -413,7 +450,7 @@ export class AngularEditorComponent implements OnInit, ControlValueAccessor, Aft
}
filterStyles(html: string): string {
- html = html.replace('position: fixed;', '');
+ html = html.replace("position: fixed;", "");
return html;
}
}
diff --git a/projects/angular-editor/src/lib/angular-editor.service.ts b/projects/angular-editor/src/lib/angular-editor.service.ts
index 12086dbc3..088aba82f 100644
--- a/projects/angular-editor/src/lib/angular-editor.service.ts
+++ b/projects/angular-editor/src/lib/angular-editor.service.ts
@@ -1,8 +1,8 @@
-import {Inject, Injectable} from '@angular/core';
-import {HttpClient, HttpEvent} from '@angular/common/http';
-import {Observable} from 'rxjs';
-import {DOCUMENT} from '@angular/common';
-import {CustomClass} from './config';
+import { Inject, Injectable } from "@angular/core";
+import { HttpClient, HttpEvent } from "@angular/common/http";
+import { Observable } from "rxjs";
+import { DOCUMENT } from "@angular/common";
+import { CustomClass } from "./config";
export interface UploadResponse {
imageUrl: string;
@@ -10,25 +10,21 @@ export interface UploadResponse {
@Injectable()
export class AngularEditorService {
-
savedSelection: Range | null;
selectedText: string;
uploadUrl: string;
uploadWithCredentials: boolean;
- constructor(
- private http: HttpClient,
- @Inject(DOCUMENT) private doc: any
- ) { }
+ constructor(private http: HttpClient, @Inject(DOCUMENT) private doc: any) {}
/**
* Executed command from editor header buttons exclude toggleEditorMode
* @param command string from triggerCommand
*/
executeCommand(command: string) {
- const commands = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 'pre'];
+ const commands = ["h1", "h2", "h3", "h4", "h5", "h6", "p", "pre"];
if (commands.includes(command)) {
- this.doc.execCommand('formatBlock', false, command);
+ this.doc.execCommand("formatBlock", false, command);
return;
}
this.doc.execCommand(command, false, null);
@@ -39,10 +35,11 @@ export class AngularEditorService {
* @param url string from UI prompt
*/
createLink(url: string) {
- if (!url.includes('http')) {
- this.doc.execCommand('createlink', false, url);
+ if (!url.includes("http")) {
+ this.doc.execCommand("createlink", false, url);
} else {
- const newUrl = '' + this.selectedText + '';
+ const newUrl =
+ '' + this.selectedText + "";
this.insertHtml(newUrl);
}
}
@@ -56,10 +53,10 @@ export class AngularEditorService {
insertColor(color: string, where: string): void {
const restored = this.restoreSelection();
if (restored) {
- if (where === 'textColor') {
- this.doc.execCommand('foreColor', false, color);
+ if (where === "textColor") {
+ this.doc.execCommand("foreColor", false, color);
} else {
- this.doc.execCommand('hiliteColor', false, color);
+ this.doc.execCommand("hiliteColor", false, color);
}
}
}
@@ -69,7 +66,7 @@ export class AngularEditorService {
* @param fontName string
*/
setFontName(fontName: string) {
- this.doc.execCommand('fontName', false, fontName);
+ this.doc.execCommand("fontName", false, fontName);
}
/**
@@ -77,7 +74,7 @@ export class AngularEditorService {
* @param fontSize string
*/
setFontSize(fontSize: string) {
- this.doc.execCommand('fontSize', false, fontSize);
+ this.doc.execCommand("fontSize", false, fontSize);
}
/**
@@ -85,11 +82,9 @@ export class AngularEditorService {
* @param html HTML string
*/
insertHtml(html: string): void {
-
- const isHTMLInserted = this.doc.execCommand('insertHTML', false, html);
-
+ const isHTMLInserted = this.doc.execCommand("insertHTML", false, html);
if (!isHTMLInserted) {
- throw new Error('Unable to perform the operation');
+ throw new Error("Unable to perform the operation");
}
}
@@ -108,7 +103,7 @@ export class AngularEditorService {
} else {
this.savedSelection = null;
}
- }
+ };
/**
* restore selection when the editor is focused in
@@ -134,17 +129,19 @@ export class AngularEditorService {
/**
* setTimeout used for execute 'saveSelection' method in next event loop iteration
*/
- public executeInNextQueueIteration(callbackFn: (...args: any[]) => any, timeout = 1e2): void {
+ public executeInNextQueueIteration(
+ callbackFn: (...args: any[]) => any,
+ timeout = 1e2
+ ): void {
setTimeout(callbackFn, timeout);
}
/** check any selection is made or not */
private checkSelection(): any {
-
const selectedText = this.savedSelection.toString();
if (selectedText.length === 0) {
- throw new Error('No Selection Made');
+ throw new Error("No Selection Made");
}
return true;
}
@@ -154,14 +151,13 @@ export class AngularEditorService {
* @param file The file
*/
uploadImage(file: File): Observable> {
-
const uploadData: FormData = new FormData();
- uploadData.append('file', file, file.name);
+ uploadData.append("file", file, file.name);
return this.http.post(this.uploadUrl, uploadData, {
reportProgress: true,
- observe: 'events',
+ observe: "events",
withCredentials: this.uploadWithCredentials,
});
}
@@ -171,33 +167,42 @@ export class AngularEditorService {
* @param imageUrl The imageUrl.
*/
insertImage(imageUrl: string) {
- this.doc.execCommand('insertImage', false, imageUrl);
+ this.doc.execCommand("insertImage", false, imageUrl);
}
setDefaultParagraphSeparator(separator: string) {
- this.doc.execCommand('defaultParagraphSeparator', false, separator);
+ this.doc.execCommand("defaultParagraphSeparator", false, separator);
}
createCustomClass(customClass: CustomClass) {
let newTag = this.selectedText;
if (customClass) {
- const tagName = customClass.tag ? customClass.tag : 'span';
- newTag = '<' + tagName + ' class="' + customClass.class + '">' + this.selectedText + '' + tagName + '>';
+ const tagName = customClass.tag ? customClass.tag : "span";
+ newTag =
+ "<" +
+ tagName +
+ ' class="' +
+ customClass.class +
+ '">' +
+ this.selectedText +
+ "" +
+ tagName +
+ ">";
}
this.insertHtml(newTag);
}
insertVideo(videoUrl: string) {
- if (videoUrl.match('www.youtube.com')) {
+ if (videoUrl.match("www.youtube.com")) {
this.insertYouTubeVideoTag(videoUrl);
}
- if (videoUrl.match('vimeo.com')) {
+ if (videoUrl.match("vimeo.com")) {
this.insertVimeoVideoTag(videoUrl);
}
}
private insertYouTubeVideoTag(videoUrl: string): void {
- const id = videoUrl.split('v=')[1];
+ const id = videoUrl.split("v=")[1];
const imageUrl = `https://img.youtube.com/vi/${id}/0.jpg`;
const thumbnail = `
@@ -211,16 +216,18 @@ export class AngularEditorService {
}
private insertVimeoVideoTag(videoUrl: string): void {
- const sub = this.http.get
(`https://vimeo.com/api/oembed.json?url=${videoUrl}`).subscribe(data => {
- const imageUrl = data.thumbnail_url_with_play_button;
- const thumbnail = `
+ const sub = this.http
+ .get
(`https://vimeo.com/api/oembed.json?url=${videoUrl}`)
+ .subscribe((data) => {
+ const imageUrl = data.thumbnail_url_with_play_button;
+ const thumbnail = ``;
- this.insertHtml(thumbnail);
- sub.unsubscribe();
- });
+ this.insertHtml(thumbnail);
+ sub.unsubscribe();
+ });
}
nextNode(node) {
@@ -248,7 +255,7 @@ export class AngularEditorService {
} else {
// Iterate nodes until we hit the end container
while (node && node !== endNode) {
- rangeNodes.push( node = this.nextNode(node) );
+ rangeNodes.push((node = this.nextNode(node)));
}
// Add partially selected nodes at the start of the range
@@ -276,7 +283,10 @@ export class AngularEditorService {
if (this.doc.getSelection) {
const sel = this.doc.getSelection();
for (let i = 0, len = sel.rangeCount; i < len; ++i) {
- nodes.push.apply(nodes, this.getRangeSelectedNodes(sel.getRangeAt(i), true));
+ nodes.push.apply(
+ nodes,
+ this.getRangeSelectedNodes(sel.getRangeAt(i), true)
+ );
}
}
return nodes;
@@ -291,10 +301,12 @@ export class AngularEditorService {
}
removeSelectedElements(tagNames) {
- const tagNamesArray = tagNames.toLowerCase().split(',');
+ const tagNamesArray = tagNames.toLowerCase().split(",");
this.getSelectedNodes().forEach((node) => {
- if (node.nodeType === 1 &&
- tagNamesArray.indexOf(node.tagName.toLowerCase()) > -1) {
+ if (
+ node.nodeType === 1 &&
+ tagNamesArray.indexOf(node.tagName.toLowerCase()) > -1
+ ) {
// Remove the node and replace it with its children
this.replaceWithOwnChildren(node);
}