File
Blob: src/client/components/editor/extensions/image/node.ts
| 1 | import { mergeAttributes } from "@tiptap/core"; |
| 2 | import type { ImageOptions } from "@tiptap/extension-image"; |
| 3 | import { ReactNodeViewRenderer } from "@tiptap/react"; |
| 4 | import { SharedImage } from "@/shared/editor/schema"; |
| 5 | import type { EditorRuntimeSnapshot } from "../../editor-runtime-context"; |
| 6 | import { resolveShareUrl } from "../../lib/media-actions"; |
| 7 | import { ImageNodeView } from "./node-view"; |
| 8 | |
| 9 | interface ShareAwareImageOptions extends ImageOptions { |
| 10 | getRuntime: () => EditorRuntimeSnapshot; |
| 11 | } |
| 12 | |
| 13 | const EMPTY_RUNTIME: EditorRuntimeSnapshot = { |
| 14 | workspaceId: undefined, |
| 15 | pageId: "", |
| 16 | shareToken: undefined, |
| 17 | }; |
| 18 | |
| 19 | export const ShareAwareImage = SharedImage.extend<ShareAwareImageOptions>({ |
| 20 | addOptions() { |
| 21 | const parent = this.parent?.(); |
| 22 | return { |
| 23 | ...parent, |
| 24 | inline: parent?.inline ?? false, |
| 25 | allowBase64: parent?.allowBase64 ?? false, |
| 26 | HTMLAttributes: parent?.HTMLAttributes ?? {}, |
| 27 | resize: parent?.resize ?? false, |
| 28 | getRuntime: () => EMPTY_RUNTIME, |
| 29 | }; |
| 30 | }, |
| 31 | renderHTML({ HTMLAttributes }) { |
| 32 | const src = typeof HTMLAttributes.src === "string" ? HTMLAttributes.src : ""; |
| 33 | const shareToken = this.options.getRuntime().shareToken; |
| 34 | |
| 35 | return [ |
| 36 | "img", |
| 37 | mergeAttributes(this.options.HTMLAttributes, { |
| 38 | ...HTMLAttributes, |
| 39 | src: resolveShareUrl(src, shareToken), |
| 40 | }), |
| 41 | ]; |
| 42 | }, |
| 43 | addNodeView() { |
| 44 | return ReactNodeViewRenderer(ImageNodeView); |
| 45 | }, |
| 46 | }); |