我想用tiptap扩展实现图像和可编辑标题
https://discuss.prosemirror.net/t/figure-and-editable-caption/462
ProseMirror有一个很好的例子,但是用tiptap很难实现吗?
如果可能的话,请告诉我你应该写什么代码。
我附上我在下面写的代码。
图片和标题已成功添加,但标题尚无法编辑。
// ./CustomImage.ts
// @ts-ignore
import { Node, Plugin } from 'tiptap'
// @ts-ignore
import { nodeInputRule } from 'tiptap-commands'
const IMAGE_INPUT_REGEX = /!\[(.+|:?)\]\((\S+)(?:(?:\s+)["'](\S+)["'])?\)/
export default class CustomImage extends Node {
get name () {
return 'customImage'
}
get schema () {
return {
attrs: {
src: {
default: null
},
alt: {
default: null
},
title: {
default: null
},
caption: {
default: null
}
},
group: 'block',
selectable: false,
draggable: true,
parseDOM: [
{
tag: 'figure'
},
[
{
tag: 'img[src]',
getAttrs: (dom: any) => ({
src: dom.getAttribute('src'),
title: dom.getAttribute('title'),
alt: dom.getAttribute('alt')
})
},
{
tag: 'figcaption'
}
]
],
toDOM: (node: any) => [
'figure',
[
'img',
{
src: node.attrs.src,
title: node.attrs.title,
alt: node.attrs.alt
}
],
[
'figcaption',
{
contenteditable: 'true'
},
node.attrs.caption
]
]
}
}
commands ({ type }: any) {
return (attrs: any) => (state: any, dispatch: any) => {
const { selection } = state
const position = selection.$cursor ? selection.$cursor.pos : selection.$to.pos
const node = type.create(attrs)
const transaction = state.tr.insert(position, node)
dispatch(transaction)
}
}
inputRules ({ type }: any) {
return [
nodeInputRule(IMAGE_INPUT_REGEX, type, (match: any) => {
const [, alt, src, title] = match
return {
src,
alt,
title
}
})
]
}
get plugins () {
return [
new Plugin({
props: {
handleDOMEvents: {
drop (view: any, event: any) {
const hasFiles = event.dataTransfer &&
event.dataTransfer.files &&
event.dataTransfer.files.length
if (!hasFiles) {
return
}
const images = Array
.from(event.dataTransfer.files)
.filter((file: any) => (/image/i).test(file.type))
if (images.length === 0) {
return
}
event.preventDefault()
const { schema } = view.state
const coordinates = view.posAtCoords({ left: event.clientX, top: event.clientY })
images.forEach((image: any) => {
const reader = new FileReader()
reader.onload = (readerEvent: any) => {
const node = schema.nodes.image.create({
src: readerEvent.target.result
})
const transaction = view.state.tr.insert(coordinates.pos, node)
view.dispatch(transaction)
}
reader.readAsDataURL(image)
})
}
}
}
})
]
}
}