diff --git a/src/app/components/components.module.ts b/src/app/components/components.module.ts
index cd9a930..a9ea8e5 100644
--- a/src/app/components/components.module.ts
+++ b/src/app/components/components.module.ts
@@ -33,6 +33,7 @@ import {MarkdownModule} from 'ngx-markdown';
import {VersionModalComponent} from './version-modal/version-modal.component';
import {EditorPageRoutingModule} from '../pages/editor/editor-routing.module';
import {EditorPage} from '../pages/editor/editor.page';
+import {WysiwygComponent} from './wysiwyg/wysiwyg.component';
@NgModule({
declarations: [
@@ -61,6 +62,7 @@ import {EditorPage} from '../pages/editor/editor.page';
MarkdownEditorComponent,
VersionModalComponent,
EditorPage,
+ WysiwygComponent,
],
imports: [
CommonModule,
@@ -100,6 +102,7 @@ import {EditorPage} from '../pages/editor/editor.page';
MarkdownEditorComponent,
VersionModalComponent,
EditorPage,
+ WysiwygComponent,
],
exports: [
NodePickerComponent,
@@ -127,6 +130,7 @@ import {EditorPage} from '../pages/editor/editor.page';
MarkdownEditorComponent,
VersionModalComponent,
EditorPage,
+ WysiwygComponent,
]
})
export class ComponentsModule {}
diff --git a/src/app/components/nodes/norm/norm.component.html b/src/app/components/nodes/norm/norm.component.html
index 3964bae..53fdfd8 100644
--- a/src/app/components/nodes/norm/norm.component.html
+++ b/src/app/components/nodes/norm/norm.component.html
@@ -1,83 +1,7 @@
-
-
-
-
+
+
\ No newline at end of file
diff --git a/src/app/components/nodes/norm/norm.component.ts b/src/app/components/nodes/norm/norm.component.ts
index d5db4d2..955cced 100644
--- a/src/app/components/nodes/norm/norm.component.ts
+++ b/src/app/components/nodes/norm/norm.component.ts
@@ -12,16 +12,10 @@ export class NormComponent extends EditorNodeContract implements OnInit {
@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;
-
- public get displayContents() {
- return this.contents.replace(/ `
${val}`);
- }
constructor(
public editorService: EditorService,
@@ -39,6 +33,10 @@ export class NormComponent extends EditorNodeContract implements OnInit {
return this.dirtyOverride || this.contents !== this.savedValue;
}
+ public get isReadonly(): boolean {
+ return !this.editorService.canEdit();
+ }
+
public writeChangesToNode(): void | Promise
{
this.nodeRec.value = this.contents;
this.savedValue = this.contents;
@@ -60,75 +58,10 @@ export class NormComponent extends EditorNodeContract implements OnInit {
});
}
- 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;
+ if ( this.contents !== contents ) {
+ this.contents = contents;
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');
- }
}
diff --git a/src/app/components/wysiwyg/wysiwyg.component.html b/src/app/components/wysiwyg/wysiwyg.component.html
new file mode 100644
index 0000000..9ec7b4f
--- /dev/null
+++ b/src/app/components/wysiwyg/wysiwyg.component.html
@@ -0,0 +1,83 @@
+
\ No newline at end of file
diff --git a/src/app/components/wysiwyg/wysiwyg.component.scss b/src/app/components/wysiwyg/wysiwyg.component.scss
new file mode 100644
index 0000000..8eb25b8
--- /dev/null
+++ b/src/app/components/wysiwyg/wysiwyg.component.scss
@@ -0,0 +1,46 @@
+.editable-base {
+ padding: 20px;
+
+ &.focused {
+ background: aliceblue;
+ }
+}
+
+.toolbar-base {
+ height: 40px;
+ border: 1px solid lightgray;
+ border-radius: 5px;
+ display: flex;
+ flex-direction: row;
+
+ .toolbar-button {
+ height: calc(100% - 6px);
+ min-width: 30px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ margin: 3px;
+
+ &:hover {
+ background: lightgrey;
+ cursor: pointer;
+ }
+ }
+
+ .toolbar-sep {
+ height: 100%;
+ width: 1px;
+ border: 1px solid lightgrey;
+ margin: 0 5px;
+ }
+}
+
+.container.dark {
+ .editable-base.focused {
+ background: #404040 !important;
+ }
+
+ .toolbar-base .toolbar-button:hover {
+ background: #404040;
+ }
+}
diff --git a/src/app/components/wysiwyg/wysiwyg.component.ts b/src/app/components/wysiwyg/wysiwyg.component.ts
new file mode 100644
index 0000000..e89b897
--- /dev/null
+++ b/src/app/components/wysiwyg/wysiwyg.component.ts
@@ -0,0 +1,102 @@
+import {Component, EventEmitter, HostListener, Input, OnInit, Output, ViewChild} from '@angular/core';
+
+@Component({
+ selector: 'wysiwyg-editor',
+ templateUrl: './wysiwyg.component.html',
+ styleUrls: ['./wysiwyg.component.scss'],
+})
+export class WysiwygComponent implements OnInit {
+ @ViewChild('editable') editable;
+ @Input() readonly = false;
+ @Input() contents = '';
+ @Output() contentsChanged: EventEmitter = new EventEmitter();
+
+ public isFocused = false;
+ protected hadOneFocusOut = false;
+ public initialValue = '';
+
+ public get displayContents() {
+ return this.contents.replace(/ `${val}`);
+ }
+
+ public isDark() {
+ return document.body.classList.contains('dark');
+ }
+
+ ngOnInit() {
+ this.initialValue = this.contents;
+ }
+
+ onFocusIn(event: MouseEvent) {
+ console.log('on focus in', event);
+ this.isFocused = !this.readonly;
+ }
+
+ @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.contentsChanged.emit(innerHTML);
+ }
+ }
+
+ @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');
+ }
+}