]> BookStack Code Mirror - bookstack/blobdiff - resources/js/wysiwyg/index.ts
ZIP Imports: Added API examples, finished testing
[bookstack] / resources / js / wysiwyg / index.ts
index 8e98780d58574c4ca98fc9fba2a904ddcd3e1e3d..f572f9de5ec9da58fc890b93b8efced42de8ab7d 100644 (file)
@@ -2,9 +2,9 @@ import {createEditor, LexicalEditor} from 'lexical';
 import {createEmptyHistoryState, registerHistory} from '@lexical/history';
 import {registerRichText} from '@lexical/rich-text';
 import {mergeRegister} from '@lexical/utils';
-import {getNodesForPageEditor, registerCommonNodeMutationListeners} from './nodes';
+import {getNodesForBasicEditor, getNodesForPageEditor, registerCommonNodeMutationListeners} from './nodes';
 import {buildEditorUI} from "./ui";
-import {getEditorContentAsHtml, setEditorContentFromHtml} from "./utils/actions";
+import {focusEditor, getEditorContentAsHtml, setEditorContentFromHtml} from "./utils/actions";
 import {registerTableResizer} from "./ui/framework/helpers/table-resizer";
 import {EditorUiContext} from "./ui/framework/core";
 import {listen as listenToCommonEvents} from "./services/common-events";
@@ -15,7 +15,7 @@ import {registerShortcuts} from "./services/shortcuts";
 import {registerNodeResizer} from "./ui/framework/helpers/node-resizer";
 import {registerKeyboardHandling} from "./services/keyboard-handling";
 import {registerAutoLinks} from "./services/auto-links";
-import {contextToolbars, getMainEditorFullToolbar} from "./ui/defaults/toolbars";
+import {contextToolbars, getBasicEditorToolbar, getMainEditorFullToolbar} from "./ui/defaults/toolbars";
 import {modals} from "./ui/defaults/modals";
 import {CodeBlockDecorator} from "./ui/decorators/code-block";
 import {DiagramDecorator} from "./ui/decorators/diagram";
@@ -90,20 +90,20 @@ export function createPageEditorInstance(container: HTMLElement, htmlContent: st
 
     registerCommonNodeMutationListeners(context);
 
-    return new SimpleWysiwygEditorInterface(editor);
+    return new SimpleWysiwygEditorInterface(context);
 }
 
-export function createCommentEditorInstance(container: HTMLElement, htmlContent: string, options: Record<string, any> = {}): SimpleWysiwygEditorInterface {
+export function createBasicEditorInstance(container: HTMLElement, htmlContent: string, options: Record<string, any> = {}): SimpleWysiwygEditorInterface {
     const editor = createEditor({
-        namespace: 'BookStackCommentEditor',
-        nodes: getNodesForPageEditor(),
+        namespace: 'BookStackBasicEditor',
+        nodes: getNodesForBasicEditor(),
         onError: console.error,
         theme: theme,
     });
     const context: EditorUiContext = buildEditorUI(container, editor, options);
     editor.setRootElement(context.editorDOM);
 
-    mergeRegister(
+    const editorTeardown = mergeRegister(
         registerRichText(editor),
         registerHistory(editor, createEmptyHistoryState(), 300),
         registerShortcuts(context),
@@ -111,23 +111,55 @@ export function createCommentEditorInstance(container: HTMLElement, htmlContent:
     );
 
     // Register toolbars, modals & decorators
-    context.manager.setToolbar(getMainEditorFullToolbar(context)); // TODO - Create comment toolbar
+    context.manager.setToolbar(getBasicEditorToolbar(context));
     context.manager.registerContextToolbar('link', contextToolbars.link);
     context.manager.registerModal('link', modals.link);
+    context.manager.onTeardown(editorTeardown);
 
     setEditorContentFromHtml(editor, htmlContent);
 
-    return new SimpleWysiwygEditorInterface(editor);
+    return new SimpleWysiwygEditorInterface(context);
 }
 
 export class SimpleWysiwygEditorInterface {
-    protected editor: LexicalEditor;
+    protected context: EditorUiContext;
+    protected onChangeListeners: (() => void)[] = [];
+    protected editorListenerTeardown: (() => void)|null = null;
 
-    constructor(editor: LexicalEditor) {
-        this.editor = editor;
+    constructor(context: EditorUiContext) {
+        this.context = context;
     }
 
     async getContentAsHtml(): Promise<string> {
-        return await getEditorContentAsHtml(this.editor);
+        return await getEditorContentAsHtml(this.context.editor);
+    }
+
+    onChange(listener: () => void) {
+        this.onChangeListeners.push(listener);
+        this.startListeningToChanges();
+    }
+
+    focus(): void {
+        focusEditor(this.context.editor);
+    }
+
+    remove() {
+        this.context.manager.teardown();
+        this.context.containerDOM.remove();
+        if (this.editorListenerTeardown) {
+            this.editorListenerTeardown();
+        }
+    }
+
+    protected startListeningToChanges(): void {
+        if (this.editorListenerTeardown) {
+            return;
+        }
+
+        this.editorListenerTeardown = this.context.editor.registerUpdateListener(() => {
+             for (const listener of this.onChangeListeners) {
+                 listener();
+             }
+        });
     }
 }
\ No newline at end of file