Skip to content
File

Blob: src/client/components/editor/extensions/image/node.ts

typescript47 lines
1import { mergeAttributes } from "@tiptap/core";
2import type { ImageOptions } from "@tiptap/extension-image";
3import { ReactNodeViewRenderer } from "@tiptap/react";
4import { SharedImage } from "@/shared/editor/schema";
5import type { EditorRuntimeSnapshot } from "../../editor-runtime-context";
6import { resolveShareUrl } from "../../lib/media-actions";
7import { ImageNodeView } from "./node-view";
8 
9interface ShareAwareImageOptions extends ImageOptions {
10 getRuntime: () => EditorRuntimeSnapshot;
11}
12 
13const EMPTY_RUNTIME: EditorRuntimeSnapshot = {
14 workspaceId: undefined,
15 pageId: "",
16 shareToken: undefined,
17};
18 
19export 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});