X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/a27a325af77e31a184cdb33dc05cb658de697e0b..cd84d08157255dd2464a6dcc257355ffeca21c96:/resources/js/wysiwyg/ui/defaults/forms/objects.ts diff --git a/resources/js/wysiwyg/ui/defaults/forms/objects.ts b/resources/js/wysiwyg/ui/defaults/forms/objects.ts index 7a388751b..228566d44 100644 --- a/resources/js/wysiwyg/ui/defaults/forms/objects.ts +++ b/resources/js/wysiwyg/ui/defaults/forms/objects.ts @@ -1,31 +1,83 @@ -import {EditorFormDefinition, EditorFormTabs, EditorSelectFormFieldDefinition} from "../../framework/forms"; +import { + EditorFormDefinition, + EditorFormField, + EditorFormTabs, + EditorSelectFormFieldDefinition +} from "../../framework/forms"; import {EditorUiContext} from "../../framework/core"; -import {$createTextNode, $getSelection} from "lexical"; -import {$createImageNode} from "../../../nodes/image"; -import {$createLinkNode} from "@lexical/link"; +import {$createNodeSelection, $createTextNode, $getSelection, $insertNodes, $setSelection} from "lexical"; +import {$isImageNode, ImageNode} from "../../../nodes/image"; +import {$createLinkNode, $isLinkNode, LinkNode} from "@lexical/link"; import {$createMediaNodeFromHtml, $createMediaNodeFromSrc, $isMediaNode, MediaNode} from "../../../nodes/media"; -import {$getNodeFromSelection} from "../../../helpers"; import {$insertNodeToNearestRoot} from "@lexical/utils"; +import {$getNodeFromSelection, getLastSelection} from "../../../utils/selection"; +import {EditorFormModal} from "../../framework/modals"; +import {EditorActionField} from "../../framework/blocks/action-field"; +import {EditorButton} from "../../framework/buttons"; +import {showImageManager} from "../../../utils/images"; +import searchImageIcon from "@icons/editor/image-search.svg"; +import searchIcon from "@icons/search.svg"; +import {showLinkSelector} from "../../../utils/links"; +import {LinkField} from "../../framework/blocks/link-field"; +import {insertOrUpdateLink} from "../../../utils/formats"; + +export function $showImageForm(image: ImageNode, context: EditorUiContext) { + const imageModal: EditorFormModal = context.manager.createModal('image'); + const height = image.getHeight(); + const width = image.getWidth(); + + const formData = { + src: image.getSrc(), + alt: image.getAltText(), + height: height === 0 ? '' : String(height), + width: width === 0 ? '' : String(width), + }; + + imageModal.show(formData); +} export const image: EditorFormDefinition = { submitText: 'Apply', async action(formData, context: EditorUiContext) { context.editor.update(() => { - const selection = $getSelection(); - const imageNode = $createImageNode(formData.get('src')?.toString() || '', { - alt: formData.get('alt')?.toString() || '', - height: Number(formData.get('height')?.toString() || '0'), - width: Number(formData.get('width')?.toString() || '0'), - }); - selection?.insertNodes([imageNode]); + const selection = getLastSelection(context.editor); + const selectedImage = $getNodeFromSelection(selection, $isImageNode); + if ($isImageNode(selectedImage)) { + selectedImage.setSrc(formData.get('src')?.toString() || ''); + selectedImage.setAltText(formData.get('alt')?.toString() || ''); + + selectedImage.setWidth(Number(formData.get('width')?.toString() || '0')); + selectedImage.setHeight(Number(formData.get('height')?.toString() || '0')); + } }); return true; }, fields: [ { - label: 'Source', - name: 'src', - type: 'text', + build() { + return new EditorActionField( + new EditorFormField({ + label: 'Source', + name: 'src', + type: 'text', + }), + new EditorButton({ + label: 'Browse files', + icon: searchImageIcon, + action(context: EditorUiContext) { + showImageManager((image) => { + const modal = context.manager.getActiveModal('image'); + if (modal) { + modal.getForm().setValues({ + src: image.thumbs?.display || image.url, + alt: image.name, + }); + } + }); + } + }), + ); + }, }, { label: 'Alternative description', @@ -45,28 +97,72 @@ export const image: EditorFormDefinition = { ], }; -export const link: EditorFormDefinition = { - submitText: 'Apply', - async action(formData, context: EditorUiContext) { +export function $showLinkForm(link: LinkNode|null, context: EditorUiContext) { + const linkModal = context.manager.createModal('link'); + + if (link) { + const formDefaults: Record = { + url: link.getURL(), + text: link.getTextContent(), + title: link.getTitle() || '', + target: link.getTarget() || '', + } + context.editor.update(() => { + const selection = $createNodeSelection(); + selection.add(link.getKey()); + $setSelection(selection); + }); + linkModal.show(formDefaults); + } else { + context.editor.getEditorState().read(() => { const selection = $getSelection(); + const text = selection?.getTextContent() || ''; + const formDefaults = {text}; + linkModal.show(formDefaults); + }); + } +} - const linkNode = $createLinkNode(formData.get('url')?.toString() || '', { - title: formData.get('title')?.toString() || '', - target: formData.get('target')?.toString() || '', - }); - linkNode.append($createTextNode(formData.get('text')?.toString() || '')); - - selection?.insertNodes([linkNode]); +export const link: EditorFormDefinition = { + submitText: 'Apply', + async action(formData, context: EditorUiContext) { + insertOrUpdateLink(context.editor, { + url: formData.get('url')?.toString() || '', + title: formData.get('title')?.toString() || '', + target: formData.get('target')?.toString() || '', + text: formData.get('text')?.toString() || '', }); return true; }, fields: [ { - label: 'URL', - name: 'url', - type: 'text', + build() { + return new EditorActionField( + new LinkField(new EditorFormField({ + label: 'URL', + name: 'url', + type: 'text', + })), + new EditorButton({ + label: 'Browse links', + icon: searchIcon, + action(context: EditorUiContext) { + showLinkSelector(entity => { + const modal = context.manager.getActiveModal('link'); + if (modal) { + modal.getForm().setValues({ + url: entity.link, + text: entity.name, + title: entity.name, + }); + } + }); + } + }), + ); + }, }, { label: 'Text to display', @@ -107,7 +203,7 @@ export const media: EditorFormDefinition = { if (selectedNode && node) { selectedNode.replace(node) } else if (node) { - $insertNodeToNearestRoot(node); + $insertNodes([node]); } }); @@ -123,7 +219,7 @@ export const media: EditorFormDefinition = { updateNode.setSrc(src); updateNode.setWidthAndHeight(width, height); if (!selectedNode) { - $insertNodeToNearestRoot(updateNode); + $insertNodes([updateNode]); } });