webapp/src/components/EditorNew/prosemirror/views/image.ts
2022-11-10 16:00:38 +01:00

69 lines
2.0 KiB
TypeScript

import type { EditorView, NodeView, NodeViewConstructor } from 'prosemirror-view'
import type { Node } from 'prosemirror-model'
class ImageView implements NodeView {
node: Node
view: EditorView
getPos: () => number
dom: Element
container: HTMLElement
handle: HTMLElement
onResizeFn: any
onResizeEndFn: any
width: number
updating: number
constructor(node: Node, view: EditorView, getPos: () => number) {
this.node = node
this.view = view
this.getPos = getPos
this.onResizeFn = this.onResize.bind(this)
this.onResizeEndFn = this.onResizeEnd.bind(this)
this.container = document.createElement('span')
this.container.className = 'image-container'
if (node.attrs.width) this.setWidth(node.attrs.width)
const image = document.createElement('img')
image.setAttribute('title', node.attrs.title ?? '')
image.setAttribute('src', node.attrs.src)
this.handle = document.createElement('span')
this.handle.className = 'resize-handle'
this.handle.addEventListener('mousedown', (e) => {
e.preventDefault()
window.addEventListener('mousemove', this.onResizeFn)
window.addEventListener('mouseup', this.onResizeEndFn)
})
this.container.appendChild(image)
this.container.appendChild(this.handle)
this.dom = this.container
}
onResize(e: MouseEvent) {
this.width = e.pageX - this.container.getBoundingClientRect().left
this.setWidth(this.width)
}
onResizeEnd() {
window.removeEventListener('mousemove', this.onResizeFn)
if (this.updating === this.width) return
this.updating = this.width
const tr = this.view.state.tr
tr.setNodeMarkup(this.getPos(), undefined, {
...this.node.attrs,
width: this.width
})
this.view.dispatch(tr)
}
setWidth(width: number) {
this.container.style.width = width + 'px'
}
}
export const createImageView: NodeViewConstructor = (node: Node, view: EditorView, getPos: () => number) =>
new ImageView(node, view, getPos)