diff options
Diffstat (limited to 'app/assets/javascripts/content_editor/extensions/image.js')
-rw-r--r-- | app/assets/javascripts/content_editor/extensions/image.js | 103 |
1 files changed, 2 insertions, 101 deletions
diff --git a/app/assets/javascripts/content_editor/extensions/image.js b/app/assets/javascripts/content_editor/extensions/image.js index 4dd8a1376ad..c9e8dfa4ad9 100644 --- a/app/assets/javascripts/content_editor/extensions/image.js +++ b/app/assets/javascripts/content_editor/extensions/image.js @@ -1,58 +1,14 @@ import { Image } from '@tiptap/extension-image'; import { VueNodeViewRenderer } from '@tiptap/vue-2'; -import { Plugin, PluginKey } from 'prosemirror-state'; -import { __ } from '~/locale'; import ImageWrapper from '../components/wrappers/image.vue'; -import { uploadFile } from '../services/upload_file'; -import { getImageAlt, readFileAsDataURL } from '../services/utils'; - -export const acceptedMimes = ['image/jpeg', 'image/png', 'image/gif', 'image/jpg']; const resolveImageEl = (element) => element.nodeName === 'IMG' ? element : element.querySelector('img'); -const startFileUpload = async ({ editor, file, uploadsPath, renderMarkdown }) => { - const encodedSrc = await readFileAsDataURL(file); - const { view } = editor; - - editor.commands.setImage({ uploading: true, src: encodedSrc }); - - const { state } = view; - const position = state.selection.from - 1; - const { tr } = state; - - try { - const { src, canonicalSrc } = await uploadFile({ file, uploadsPath, renderMarkdown }); - - view.dispatch( - tr.setNodeMarkup(position, undefined, { - uploading: false, - src: encodedSrc, - alt: getImageAlt(src), - canonicalSrc, - }), - ); - } catch (e) { - editor.commands.deleteRange({ from: position, to: position + 1 }); - editor.emit('error', __('An error occurred while uploading the image. Please try again.')); - } -}; - -const handleFileEvent = ({ editor, file, uploadsPath, renderMarkdown }) => { - if (acceptedMimes.includes(file?.type)) { - startFileUpload({ editor, file, uploadsPath, renderMarkdown }); - - return true; - } - - return false; -}; - -const ExtendedImage = Image.extend({ +export default Image.extend({ defaultOptions: { ...Image.options, - uploadsPath: null, - renderMarkdown: null, + inline: true, }, addAttributes() { return { @@ -107,62 +63,7 @@ const ExtendedImage = Image.extend({ }, ]; }, - addCommands() { - return { - ...this.parent(), - uploadImage: ({ file }) => () => { - const { uploadsPath, renderMarkdown } = this.options; - - handleFileEvent({ file, uploadsPath, renderMarkdown, editor: this.editor }); - }, - }; - }, - addProseMirrorPlugins() { - const { editor } = this; - - return [ - new Plugin({ - key: new PluginKey('handleDropAndPasteImages'), - props: { - handlePaste: (_, event) => { - const { uploadsPath, renderMarkdown } = this.options; - - return handleFileEvent({ - editor, - file: event.clipboardData.files[0], - uploadsPath, - renderMarkdown, - }); - }, - handleDrop: (_, event) => { - const { uploadsPath, renderMarkdown } = this.options; - - return handleFileEvent({ - editor, - file: event.dataTransfer.files[0], - uploadsPath, - renderMarkdown, - }); - }, - }, - }), - ]; - }, addNodeView() { return VueNodeViewRenderer(ImageWrapper); }, }); - -const serializer = (state, node) => { - const { alt, canonicalSrc, src, title } = node.attrs; - const quotedTitle = title ? ` ${state.quote(title)}` : ''; - - state.write(`![${state.esc(alt || '')}](${state.esc(canonicalSrc || src)}${quotedTitle})`); -}; - -export const configure = ({ renderMarkdown, uploadsPath }) => { - return { - tiptapExtension: ExtendedImage.configure({ inline: true, renderMarkdown, uploadsPath }), - serializer, - }; -}; |