6 changed files with 165 additions and 7 deletions
@ -0,0 +1,6 @@ |
|||||
|
import { Editor } from "@tiptap/core"; |
||||
|
|
||||
|
export abstract class BasePlugin { |
||||
|
abstract register<T = object>(editor: Editor, option?: T): void |
||||
|
} |
||||
|
export default BasePlugin |
@ -0,0 +1,130 @@ |
|||||
|
import { |
||||
|
mergeAttributes, |
||||
|
Node, |
||||
|
nodeInputRule, |
||||
|
} from '@tiptap/core' |
||||
|
|
||||
|
export interface ImageOptions { |
||||
|
/** |
||||
|
* Controls if the image node should be inline or not. |
||||
|
* @default false |
||||
|
* @example true |
||||
|
*/ |
||||
|
inline: boolean, |
||||
|
|
||||
|
/** |
||||
|
* Controls if base64 images are allowed. Enable this if you want to allow |
||||
|
* base64 image urls in the `src` attribute. |
||||
|
* @default false |
||||
|
* @example true |
||||
|
*/ |
||||
|
allowBase64: boolean, |
||||
|
|
||||
|
/** |
||||
|
* HTML attributes to add to the image element. |
||||
|
* @default {} |
||||
|
* @example { class: 'foo' } |
||||
|
*/ |
||||
|
HTMLAttributes: Record<string, any>, |
||||
|
} |
||||
|
|
||||
|
declare module '@tiptap/core' { |
||||
|
interface Commands<ReturnType> { |
||||
|
image: { |
||||
|
/** |
||||
|
* Add an image |
||||
|
* @param options The image attributes |
||||
|
* @example |
||||
|
* editor |
||||
|
* .commands |
||||
|
* .setImage({ src: 'https://tiptap.dev/logo.png', alt: 'tiptap', title: 'tiptap logo' }) |
||||
|
*/ |
||||
|
setImage: (options: { src: string, alt?: string, title?: string }) => ReturnType, |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Matches an image to a  on input. |
||||
|
*/ |
||||
|
export const inputRegex = /(?:^|\s)(!\[(.+|:?)]\((\S+)(?:(?:\s+)["'](\S+)["'])?\))$/ |
||||
|
|
||||
|
/** |
||||
|
* This extension allows you to insert images. |
||||
|
* @see https://www.tiptap.dev/api/nodes/image
|
||||
|
*/ |
||||
|
export const Image = Node.create<ImageOptions>({ |
||||
|
name: 'image', |
||||
|
|
||||
|
addOptions() { |
||||
|
return { |
||||
|
inline: false, |
||||
|
allowBase64: false, |
||||
|
HTMLAttributes: {}, |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
inline() { |
||||
|
return this.options.inline |
||||
|
}, |
||||
|
|
||||
|
group() { |
||||
|
return this.options.inline ? 'inline' : 'block' |
||||
|
}, |
||||
|
|
||||
|
draggable: true, |
||||
|
|
||||
|
addAttributes() { |
||||
|
return { |
||||
|
src: { |
||||
|
default: null, |
||||
|
}, |
||||
|
alt: { |
||||
|
default: null, |
||||
|
}, |
||||
|
title: { |
||||
|
default: null, |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
parseHTML() { |
||||
|
return [ |
||||
|
{ |
||||
|
tag: this.options.allowBase64 |
||||
|
? 'img[src]' |
||||
|
: 'img[src]:not([src^="data:"])', |
||||
|
}, |
||||
|
] |
||||
|
}, |
||||
|
|
||||
|
renderHTML({ HTMLAttributes }) { |
||||
|
// return ['img', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes,{dataAa: 123})]
|
||||
|
return ['div', { "style": "display:inline-block" }, ["img", mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, { dataAa: 123 })]] |
||||
|
}, |
||||
|
|
||||
|
addCommands() { |
||||
|
return { |
||||
|
setImage: options => ({ commands }) => { |
||||
|
return commands.insertContent({ |
||||
|
type: this.name, |
||||
|
attrs: options, |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
}, |
||||
|
|
||||
|
addInputRules() { |
||||
|
return [ |
||||
|
nodeInputRule({ |
||||
|
find: inputRegex, |
||||
|
type: this.type, |
||||
|
getAttributes: match => { |
||||
|
const [, , alt, src, title] = match |
||||
|
|
||||
|
return { src, alt, title } |
||||
|
}, |
||||
|
}), |
||||
|
] |
||||
|
}, |
||||
|
}) |
@ -0,0 +1,16 @@ |
|||||
|
import { Editor } from "@tiptap/core"; |
||||
|
import { Image } from "./Image"; |
||||
|
import BasePlugin from "../../base/BasePlugin.js"; |
||||
|
|
||||
|
class ImagePlugin extends BasePlugin { |
||||
|
register(editor: Editor) { |
||||
|
editor.extensionManager.extensions.push(Image.configure({ |
||||
|
inline: true, |
||||
|
})) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export { |
||||
|
ImagePlugin |
||||
|
} |
||||
|
export default ImagePlugin |
Loading…
Reference in new issue