198 lines
5.7 KiB
TypeScript
Raw Normal View History

2019-12-02 15:31:32 +09:00
import {
Component,
OnInit,
ElementRef,
ViewChild,
AfterViewInit,
HostListener
} from '@angular/core';
@Component({
selector: 'ucap-message-editor',
templateUrl: './message-editor.component.html',
styleUrls: ['./message-editor.component.scss']
})
export class MessageEditorComponent implements OnInit, AfterViewInit {
@ViewChild('fileInput', { static: false })
fileInput: ElementRef<HTMLInputElement>;
@ViewChild('contentArea', { static: true }) contentArea: ElementRef;
attachFileType: string;
fileIndex = 0;
attachFiles: { file: File; idx: number }[] = [];
imageFiles: { file: File; idx: number }[] = [];
constructor() {}
ngOnInit() {}
ngAfterViewInit(): void {
setTimeout(() => {
this.contentArea.nativeElement.focus();
document
.querySelector('#contentArea')
.addEventListener('paste', (event: ClipboardEvent) => {
event.stopPropagation();
event.preventDefault();
const clipboardData = event.clipboardData;
let pastedData = clipboardData.getData('Text');
pastedData = this.convertHtmltoEntity(pastedData);
clipboardData.setData('Text', pastedData);
const div = document.createElement('div');
div.innerHTML = pastedData;
this.attachElementNextFocused(div);
});
document
.querySelector('#contentArea')
.addEventListener('keyup', event => {
if (
document.querySelector('#contentArea').innerHTML === '' ||
document.querySelector('#contentArea').innerHTML === '<br>'
) {
const div = document.createElement('div');
div.innerHTML = '&nbsp;<br>';
document.querySelector('#contentArea').innerHTML = '';
this.attachElementNextFocused(div);
}
});
// init..
if (document.querySelector('#contentArea').innerHTML === '') {
const div = document.createElement('div');
div.innerHTML = '&nbsp;<br>';
this.attachElementNextFocused(div);
}
}, 700);
}
onClickFileInput(type: string) {
this.attachFileType = type;
if (type === 'attach') {
this.fileInput.nativeElement.setAttribute('multiple', 'true');
this.fileInput.nativeElement.setAttribute('accept', '*.*');
} else {
this.fileInput.nativeElement.removeAttribute('multiple');
this.fileInput.nativeElement.setAttribute('accept', 'image/*');
}
this.fileInput.nativeElement.click();
}
onChangeFileInput() {
const files: FileList = this.fileInput.nativeElement.files;
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < files.length; i++) {
if (this.attachFileType === 'attach') {
this.attachFiles.push({ file: files[i], idx: this.fileIndex });
} else {
this.imageFiles.push({ file: files[i], idx: this.fileIndex });
this.addImageInInputField(files[i], this.fileIndex);
}
this.fileIndex++;
}
this.fileInput.nativeElement.value = '';
}
getContents(): string {
return 'this is contents';
}
addImageInInputField(image: File, index: number) {
const reader = new FileReader();
reader.readAsDataURL(image);
reader.onloadend = () => {
const img = document.createElement('img');
img.setAttribute('src', reader.result.toString());
img.setAttribute('data-seq', index.toString());
this.attachElementNextFocused(img);
};
}
attachElementNextFocused(el: HTMLElement) {
if (window.getSelection) {
const sel = window.getSelection();
const selAnchorNode: Node = sel.anchorNode;
const focusedEl = selAnchorNode.parentElement;
if (this.isParentIdCheck(focusedEl, 'contentArea')) {
if (sel.rangeCount) {
const range = sel.getRangeAt(0);
if (selAnchorNode.nodeType === Node.TEXT_NODE) {
const content: string = focusedEl.textContent;
focusedEl.innerText =
content.substr(0, range.startOffset) +
el.textContent +
content.substr(range.endOffset);
} else if (
selAnchorNode.nodeType === Node.ELEMENT_NODE &&
focusedEl.id === 'contentArea'
) {
const selEl = selAnchorNode as HTMLElement;
const content: string = selEl.textContent;
selEl.innerText =
content.substr(0, range.startOffset) +
el.textContent +
content.substr(range.endOffset);
} else {
focusedEl.append(el);
}
} else {
focusedEl.append(el);
}
} else {
this.contentArea.nativeElement.appendChild(el);
}
} else {
this.contentArea.nativeElement.appendChild(el);
}
}
isParentIdCheck(el: HTMLElement, id: string): boolean {
if (el.id === id) {
return true;
} else {
if (el.tagName === 'BODY' || el.tagName === 'body') {
return false;
} else {
return this.isParentIdCheck(el.parentElement, id);
}
}
}
test(): void {
if (!!this.contentArea) {
const els: HTMLCollection = this.contentArea.nativeElement.children;
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < els.length; i++) {
console.log(this.convertEntitytoHtml(els[i].textContent));
}
}
}
convertHtmltoEntity(str: string): string {
return str
.replace(/ /g, '&nbsp; ')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/\n/g, '<br>');
}
convertEntitytoHtml(str: string): string {
return str
.replace(/&nbsp;/g, ' ')
.replace(/&lt;/g, '<')
.replace(/&gt;/g, '>')
.replace(/<br>/g, ' \n');
}
}