From f92276a9d600eafb92e4ef81e879377ffc936859 Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Wed, 11 Sep 2024 10:58:13 +0530 Subject: [PATCH] feat: Add image paste plugin (#31) --- package.json | 2 +- src/plugins/image.js | 58 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/plugins/image.js diff --git a/package.json b/package.json index d5d17fa..e593515 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@chatwoot/prosemirror-schema", - "version": "1.0.16", + "version": "1.0.17", "description": "Schema setup for using prosemirror in chatwoot. Based on 👉 https://github.com/ProseMirror/prosemirror-example-setup/", "main": "dist/index.js", "scripts": { diff --git a/src/plugins/image.js b/src/plugins/image.js new file mode 100644 index 0000000..ea93254 --- /dev/null +++ b/src/plugins/image.js @@ -0,0 +1,58 @@ +import { Plugin } from "prosemirror-state"; + +/** + * Replaces an image node in the editor with a new image URL. + * + * @param {string} currentUrl - The current URL of the image to be replaced. + * @param {string} newUrl - The new URL to replace the current image with. + * @param {EditorView} view - The ProseMirror editor view. + */ +function replaceImage(currentUrl, newUrl, view) { + view.state.doc.descendants((node, pos) => { + if (node.type.name === "image" && node.attrs.src === currentUrl) { + const tr = view.state.tr.setNodeMarkup(pos, null, { + ...node.attrs, + src: newUrl, + }); + view.dispatch(tr); + } + }); +} + +/** + * Creates a ProseMirror plugin that handles image pasting and uploading. + * + * @param {Function} uploadImage - A function that takes an image URL and returns a Promise + * that resolves to the new URL after uploading. + * @returns {Plugin} A ProseMirror plugin that handles image pasting. + */ +const imagePastePlugin = (uploadImage) => + new Plugin({ + props: { + /** + * Handles the paste event in the editor. + * + * @param {EditorView} view - The ProseMirror editor view. + * @param {Event} event - The paste event. + * @param {Slice} slice - The ProseMirror Slice object representing the pasted content. + */ + handlePaste(view, event, slice) { + const imageUrls = []; + slice.content.descendants((node) => { + if (node.type.name === "image") { + imageUrls.push(node.attrs.src); + } + }); + Promise.all(imageUrls.map(async (url) => { + try { + const newUrl = await uploadImage(url); + replaceImage(url, newUrl, view); + } catch (error) { + console.error("Error uploading image:", error); + } + })); + }, + }, + }); + +export default imagePastePlugin;