webapp/src/components/EditorNew/prosemirror/plugins/image.ts

51 lines
1.4 KiB
TypeScript
Raw Normal View History

2022-11-09 17:57:35 +00:00
import { Plugin } from 'prosemirror-state'
import type { DiscoursSchema } from '../schema'
const REGEX = /^!\[([^[\]]*?)]\((.+?)\)\s+/
const MAX_MATCH = 500
const isUrl = (str: string) => {
try {
const url = new URL(str)
return url.protocol === 'http:' || url.protocol === 'https:'
} catch {
return false
}
}
const isBlank = (text: string) => text === ' ' || text === '\u00A0'
export const imageInput = (schema: DiscoursSchema) =>
new Plugin({
props: {
handleTextInput(view, from, to, text) {
if (view.composing || !isBlank(text)) return false
const $from = view.state.doc.resolve(from)
if ($from.parent.type.spec.code) return false
const textBefore =
$from.parent.textBetween(
Math.max(0, $from.parentOffset - MAX_MATCH),
$from.parentOffset,
null,
'\uFFFC'
) + text
const match = REGEX.exec(textBefore)
if (match) {
const [, title, src] = match
if (isUrl(src)) {
const node = schema.node('image', { src, title })
const start = from - (match[0].length - text.length)
const tr = view.state.tr
tr.delete(start, to)
tr.insert(start, node)
view.dispatch(tr)
return true
}
return false
}
}
}
})