X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/e889bc680b9ff5399a6a3e9fc3c89cd7127d4af2..refs/pull/5280/head:/resources/js/wysiwyg/ui/index.ts diff --git a/resources/js/wysiwyg/ui/index.ts b/resources/js/wysiwyg/ui/index.ts index b2fd7e05a..3811f44b9 100644 --- a/resources/js/wysiwyg/ui/index.ts +++ b/resources/js/wysiwyg/ui/index.ts @@ -1,70 +1,73 @@ +import {LexicalEditor} from "lexical"; import { - $getSelection, - COMMAND_PRIORITY_LOW, - LexicalEditor, - SELECTION_CHANGE_COMMAND -} from "lexical"; -import {getMainEditorFullToolbar} from "./toolbars"; + getCodeToolbarContent, + getImageToolbarContent, + getLinkToolbarContent, + getMainEditorFullToolbar, getTableToolbarContent +} from "./toolbars"; import {EditorUIManager} from "./framework/manager"; -import {image as imageFormDefinition, link as linkFormDefinition, source as sourceFormDefinition} from "./defaults/form-definitions"; -import {DecoratorListener} from "lexical/LexicalEditor"; -import type {NodeKey} from "lexical/LexicalNode"; -import {EditorDecoratorAdapter} from "./framework/decorator"; -import {ImageDecorator} from "./decorators/image"; import {EditorUiContext} from "./framework/core"; +import {CodeBlockDecorator} from "./decorators/code-block"; +import {DiagramDecorator} from "./decorators/diagram"; +import {modals} from "./defaults/modals"; -export function buildEditorUI(element: HTMLElement, editor: LexicalEditor) { +export function buildEditorUI(container: HTMLElement, element: HTMLElement, scrollContainer: HTMLElement, editor: LexicalEditor, options: Record): EditorUiContext { const manager = new EditorUIManager(); const context: EditorUiContext = { editor, + containerDOM: container, + editorDOM: element, + scrollDOM: scrollContainer, manager, - translate: (text: string): string => text, - lastSelection: null, + translate(text: string): string { + const translations = options.translations; + return translations[text] || text; + }, + error(error: string|Error): void { + const message = error instanceof Error ? error.message : error; + window.$events.error(message); // TODO - Translate + }, + options, }; manager.setContext(context); // Create primary toolbar - const toolbar = getMainEditorFullToolbar(); - toolbar.setContext(context); - element.before(toolbar.getDOMElement()); + manager.setToolbar(getMainEditorFullToolbar(context)); // Register modals - manager.registerModal('link', { - title: 'Insert/Edit link', - form: linkFormDefinition, + for (const key of Object.keys(modals)) { + manager.registerModal(key, modals[key]); + } + + // Register context toolbars + manager.registerContextToolbar('image', { + selector: 'img:not([drawio-diagram] img)', + content: getImageToolbarContent(), }); - manager.registerModal('image', { - title: 'Insert/Edit Image', - form: imageFormDefinition + manager.registerContextToolbar('link', { + selector: 'a', + content: getLinkToolbarContent(), + displayTargetLocator(originalTarget: HTMLElement): HTMLElement { + const image = originalTarget.querySelector('img'); + return image || originalTarget; + } }); - manager.registerModal('source', { - title: 'Source code', - form: sourceFormDefinition, + manager.registerContextToolbar('code', { + selector: '.editor-code-block-wrap', + content: getCodeToolbarContent(), }); - // Register decorator listener - // Maybe move to manager? - manager.registerDecoratorType('image', ImageDecorator); - const domDecorateListener: DecoratorListener = (decorators: Record) => { - const keys = Object.keys(decorators); - for (const key of keys) { - const decoratedEl = editor.getElementByKey(key); - const adapter = decorators[key]; - const decorator = manager.getDecorator(adapter.type, key); - decorator.setNode(adapter.getNode()); - const decoratorEl = decorator.render(context); - if (decoratedEl) { - decoratedEl.append(decoratorEl); - } + manager.registerContextToolbar('table', { + selector: 'td,th', + content: getTableToolbarContent(), + displayTargetLocator(originalTarget: HTMLElement): HTMLElement { + return originalTarget.closest('table') as HTMLTableElement; } - } - editor.registerDecoratorListener(domDecorateListener); + }); + + // Register image decorator listener + manager.registerDecoratorType('code', CodeBlockDecorator); + manager.registerDecoratorType('diagram', DiagramDecorator); - // Update button states on editor selection change - editor.registerCommand(SELECTION_CHANGE_COMMAND, () => { - const selection = $getSelection(); - toolbar.updateState({editor, selection}); - context.lastSelection = selection; - return false; - }, COMMAND_PRIORITY_LOW); + return context; } \ No newline at end of file