X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/483d9bf26ca5db0de17aa6fbf775874a596e4782..refs/pull/5689/head:/resources/js/wysiwyg/ui/index.ts diff --git a/resources/js/wysiwyg/ui/index.ts b/resources/js/wysiwyg/ui/index.ts index d04808fae..e7ec6adbc 100644 --- a/resources/js/wysiwyg/ui/index.ts +++ b/resources/js/wysiwyg/ui/index.ts @@ -1,52 +1,80 @@ +import {LexicalEditor} from "lexical"; import { - $getSelection, - COMMAND_PRIORITY_LOW, - LexicalEditor, - SELECTION_CHANGE_COMMAND -} from "lexical"; -import {EditorButton, EditorButtonDefinition} from "./editor-button"; -import { - blockquoteButton, boldButton, codeButton, - dangerCalloutButton, - h2Button, - h3Button, h4Button, h5Button, - infoCalloutButton, italicButton, paragraphButton, redoButton, strikethroughButton, subscriptButton, - successCalloutButton, superscriptButton, underlineButton, undoButton, - warningCalloutButton -} from "./buttons"; - - - -const toolbarButtonDefinitions: EditorButtonDefinition[] = [ - undoButton, redoButton, + getCodeToolbarContent, getDetailsToolbarContent, + getImageToolbarContent, + getLinkToolbarContent, + getMainEditorFullToolbar, getMediaToolbarContent, getTableToolbarContent +} from "./defaults/toolbars"; +import {EditorUIManager} from "./framework/manager"; +import {EditorUiContext} from "./framework/core"; +import {CodeBlockDecorator} from "./decorators/code-block"; +import {DiagramDecorator} from "./decorators/diagram"; +import {modals} from "./defaults/modals"; - infoCalloutButton, warningCalloutButton, dangerCalloutButton, successCalloutButton, - h2Button, h3Button, h4Button, h5Button, - blockquoteButton, paragraphButton, +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 { + 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); - boldButton, italicButton, underlineButton, strikethroughButton, - superscriptButton, subscriptButton, codeButton, -]; + // Create primary toolbar + manager.setToolbar(getMainEditorFullToolbar(context)); -export function buildEditorUI(element: HTMLElement, editor: LexicalEditor) { - const toolbarContainer = document.createElement('div'); - toolbarContainer.classList.add('editor-toolbar-container'); + // Register modals + for (const key of Object.keys(modals)) { + manager.registerModal(key, modals[key]); + } - const buttons = toolbarButtonDefinitions.map(definition => { - return new EditorButton(definition, editor); + // Register context toolbars + manager.registerContextToolbar('image', { + selector: 'img:not([drawio-diagram] img)', + content: getImageToolbarContent(), + }); + manager.registerContextToolbar('media', { + selector: '.editor-media-wrap', + content: getMediaToolbarContent(), + }); + manager.registerContextToolbar('link', { + selector: 'a', + content: getLinkToolbarContent(), + displayTargetLocator(originalTarget: HTMLElement): HTMLElement { + const image = originalTarget.querySelector('img'); + return image || originalTarget; + } + }); + manager.registerContextToolbar('code', { + selector: '.editor-code-block-wrap', + content: getCodeToolbarContent(), + }); + manager.registerContextToolbar('table', { + selector: 'td,th', + content: getTableToolbarContent(), + displayTargetLocator(originalTarget: HTMLElement): HTMLElement { + return originalTarget.closest('table') as HTMLTableElement; + } + }); + manager.registerContextToolbar('details', { + selector: 'details', + content: getDetailsToolbarContent(), }); - const buttonElements = buttons.map(button => button.getDOMElement()); - - toolbarContainer.append(...buttonElements); - element.before(toolbarContainer); + // 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(); - for (const button of buttons) { - button.updateActiveState(selection); - } - return false; - }, COMMAND_PRIORITY_LOW); + return context; } \ No newline at end of file