You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
frontend/src/app/components/nodes/norm/norm.component.ts

127 lines
3.6 KiB

import {Component, HostListener, Input, OnInit, ViewChild} from '@angular/core';
import {EditorNodeContract} from '../EditorNode.contract';
import {EditorService} from '../../../service/editor.service';
@Component({
selector: 'editor-norm',
templateUrl: './norm.component.html',
styleUrls: ['./norm.component.scss'],
})
export class NormComponent extends EditorNodeContract implements OnInit {
@ViewChild('editable') editable;
@Input() nodeId: string;
@Input() editorUUID?: string;
public isFocused = false;
public initialValue = 'Click to edit...';
protected savedValue = 'Click to edit...';
public contents = '';
private dirtyOverride = false;
protected hadOneFocusOut = false;
constructor(
public editorService: EditorService,
) {
super();
this.contents = this.initialValue;
this.savedValue = this.initialValue;
}
public isDirty(): boolean | Promise<boolean> {
return this.dirtyOverride || this.contents !== this.savedValue;
}
public writeChangesToNode(): void | Promise<void> {
this.nodeRec.value = this.contents;
this.savedValue = this.contents;
}
ngOnInit() {
this.editorService = this.editorService.getEditor(this.editorUUID);
this.editorService.registerNodeEditor(this.nodeId, this).then(() => {
if ( !this.node.Value ) {
this.node.Value = {};
}
if ( this.node.Value.Value ) {
this.initialValue = this.node.Value.Value;
this.savedValue = this.node.Value.Value;
}
this.contents = this.initialValue;
});
}
onFocusIn(event: MouseEvent) {
this.isFocused = this.editorService.canEdit();
}
@HostListener('document:keyup.escape', ['$event'])
onFocusOut(event) {
if ( !this.hadOneFocusOut ) {
this.hadOneFocusOut = true;
setTimeout(() => {
this.hadOneFocusOut = false;
}, 500);
} else {
this.isFocused = false;
this.hadOneFocusOut = false;
}
}
documentCommand(cmd: string) {
// Yes, technically this is deprecated, but it'll be poly-filled if necessary. Bite me.
document.execCommand(cmd, false, '');
}
onContentsChanged(contents: string) {
const innerHTML = this.editable.nativeElement.innerHTML;
if ( this.contents !== innerHTML ) {
this.contents = innerHTML;
this.editorService.triggerSave();
}
}
@HostListener('document:keydown.tab', ['$event'])
onIndent(event) {
event.preventDefault();
this.documentCommand('indent');
}
@HostListener('document:keydown.shift.tab', ['$event'])
onOutdent(event) {
event.preventDefault();
this.documentCommand('outdent');
}
@HostListener('document:keydown.control.b', ['$event'])
onBold(event) {
event.preventDefault();
this.documentCommand('bold');
}
@HostListener('document:keydown.control.i', ['$event'])
onItalic(event) {
event.preventDefault();
this.documentCommand('italic');
}
@HostListener('document:keydown.control.u', ['$event'])
onUnderline(event) {
event.preventDefault();
this.documentCommand('underline');
}
@HostListener('document:keydown.control.z', ['$event'])
onUndo(event) {
event.preventDefault();
this.documentCommand('undo');
}
@HostListener('document:keydown.control.shift.z', ['$event'])
onRedo(event) {
event.preventDefault();
this.documentCommand('redo');
}
}