refactoring

This commit is contained in:
Philipp Kühn
2021-03-08 23:10:10 +01:00
parent 7f698a7553
commit d64ddf6c1b
5 changed files with 217 additions and 211 deletions

View File

@@ -1,208 +1,208 @@
// @ts-nocheck
import { Node, NodeViewRenderer, NodeViewRendererProps } from '@tiptap/core'
import { Decoration, NodeView } from 'prosemirror-view'
import { NodeSelection } from 'prosemirror-state'
import { Node as ProseMirrorNode } from 'prosemirror-model'
import React from 'react'
import ReactDOM from 'react-dom'
import { Editor } from './Editor'
import { ReactRenderer } from './ReactRenderer'
// // @ts-nocheck
// import { Node, NodeViewRenderer, NodeViewRendererProps } from '@tiptap/core'
// import { Decoration, NodeView } from 'prosemirror-view'
// import { NodeSelection } from 'prosemirror-state'
// import { Node as ProseMirrorNode } from 'prosemirror-model'
// import React from 'react'
// import ReactDOM from 'react-dom'
// import { Editor } from './Editor'
// import { ReactRenderer } from './ReactRenderer'
interface ReactNodeViewRendererOptions {
stopEvent: ((event: Event) => boolean) | null,
update: ((node: ProseMirrorNode, decorations: Decoration[]) => boolean) | null,
}
// interface ReactNodeViewRendererOptions {
// stopEvent: ((event: Event) => boolean) | null,
// update: ((node: ProseMirrorNode, decorations: Decoration[]) => boolean) | null,
// }
class ReactNodeView implements NodeView {
// class ReactNodeView implements NodeView {
renderer!: ReactRenderer
// renderer!: ReactRenderer
editor: Editor
// editor: Editor
extension!: Node
// extension!: Node
node!: ProseMirrorNode
// node!: ProseMirrorNode
decorations!: Decoration[]
// decorations!: Decoration[]
getPos!: any
// getPos!: any
isDragging = false
// isDragging = false
options: ReactNodeViewRendererOptions = {
stopEvent: null,
update: null,
}
// options: ReactNodeViewRendererOptions = {
// stopEvent: null,
// update: null,
// }
constructor(component: any, props: NodeViewRendererProps, options?: Partial<ReactNodeViewRendererOptions>) {
this.options = { ...this.options, ...options }
this.editor = props.editor as Editor
this.extension = props.extension
this.node = props.node
this.getPos = props.getPos
this.mount(component)
}
// constructor(component: any, props: NodeViewRendererProps, options?: Partial<ReactNodeViewRendererOptions>) {
// this.options = { ...this.options, ...options }
// this.editor = props.editor as Editor
// this.extension = props.extension
// this.node = props.node
// this.getPos = props.getPos
// this.mount(component)
// }
mount(component: any) {
const props = {}
// mount(component: any) {
// const props = {}
if (!component.displayName) {
component.displayName = this.extension.config.name
}
// if (!component.displayName) {
// component.displayName = this.extension.config.name
// }
this.renderer = new ReactRenderer(component, {
editor: this.editor,
props,
})
}
// this.renderer = new ReactRenderer(component, {
// editor: this.editor,
// props,
// })
// }
get dom() {
// if (!this.renderer.element) {
// return null
// }
// get dom() {
// // if (!this.renderer.element) {
// // return null
// // }
// if (!this.renderer.element.hasAttribute('data-node-view-wrapper')) {
// throw Error('Please use the NodeViewWrapper component for your node view.')
// }
// // if (!this.renderer.element.hasAttribute('data-node-view-wrapper')) {
// // throw Error('Please use the NodeViewWrapper component for your node view.')
// // }
return this.renderer.element
}
// return this.renderer.element
// }
get contentDOM() {
// console.log(this.dom)
// return null
// if (!this.renderer.element) {
// return null
// }
// get contentDOM() {
// // console.log(this.dom)
// // return null
// // if (!this.renderer.element) {
// // return null
// // }
const hasContent = !this.node.type.isAtom
// const hasContent = !this.node.type.isAtom
if (!hasContent) {
return null
}
// if (!hasContent) {
// return null
// }
const contentElement = this.dom.querySelector('[data-node-view-content]')
// const contentElement = this.dom.querySelector('[data-node-view-content]')
return contentElement || this.dom
}
// return contentElement || this.dom
// }
stopEvent(event: Event) {
if (typeof this.options.stopEvent === 'function') {
return this.options.stopEvent(event)
}
// stopEvent(event: Event) {
// if (typeof this.options.stopEvent === 'function') {
// return this.options.stopEvent(event)
// }
const target = (event.target as HTMLElement)
const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target)
// const target = (event.target as HTMLElement)
// const isInElement = this.dom.contains(target) && !this.contentDOM?.contains(target)
// ignore all events from child nodes
if (!isInElement) {
return false
}
// // ignore all events from child nodes
// if (!isInElement) {
// return false
// }
const { isEditable } = this.editor
const { isDragging } = this
const isDraggable = !!this.node.type.spec.draggable
const isSelectable = NodeSelection.isSelectable(this.node)
const isCopyEvent = event.type === 'copy'
const isPasteEvent = event.type === 'paste'
const isCutEvent = event.type === 'cut'
const isClickEvent = event.type === 'mousedown'
const isDragEvent = event.type.startsWith('drag') || event.type === 'drop'
// const { isEditable } = this.editor
// const { isDragging } = this
// const isDraggable = !!this.node.type.spec.draggable
// const isSelectable = NodeSelection.isSelectable(this.node)
// const isCopyEvent = event.type === 'copy'
// const isPasteEvent = event.type === 'paste'
// const isCutEvent = event.type === 'cut'
// const isClickEvent = event.type === 'mousedown'
// const isDragEvent = event.type.startsWith('drag') || event.type === 'drop'
// ProseMirror tries to drag selectable nodes
// even if `draggable` is set to `false`
// this fix prevents that
if (!isDraggable && isSelectable && isDragEvent) {
event.preventDefault()
}
// // ProseMirror tries to drag selectable nodes
// // even if `draggable` is set to `false`
// // this fix prevents that
// if (!isDraggable && isSelectable && isDragEvent) {
// event.preventDefault()
// }
if (isDraggable && isDragEvent && !isDragging) {
event.preventDefault()
return false
}
// if (isDraggable && isDragEvent && !isDragging) {
// event.preventDefault()
// return false
// }
// we have to store that dragging started
if (isDraggable && isEditable && !isDragging && isClickEvent) {
const dragHandle = target.closest('[data-drag-handle]')
const isValidDragHandle = dragHandle
&& (this.dom === dragHandle || (this.dom.contains(dragHandle)))
// // we have to store that dragging started
// if (isDraggable && isEditable && !isDragging && isClickEvent) {
// const dragHandle = target.closest('[data-drag-handle]')
// const isValidDragHandle = dragHandle
// && (this.dom === dragHandle || (this.dom.contains(dragHandle)))
if (isValidDragHandle) {
this.isDragging = true
document.addEventListener('dragend', () => {
this.isDragging = false
}, { once: true })
}
}
// if (isValidDragHandle) {
// this.isDragging = true
// document.addEventListener('dragend', () => {
// this.isDragging = false
// }, { once: true })
// }
// }
// these events are handled by prosemirror
if (
isDragging
|| isCopyEvent
|| isPasteEvent
|| isCutEvent
|| (isClickEvent && isSelectable)
) {
return false
}
// // these events are handled by prosemirror
// if (
// isDragging
// || isCopyEvent
// || isPasteEvent
// || isCutEvent
// || (isClickEvent && isSelectable)
// ) {
// return false
// }
return true
}
// return true
// }
ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {
if (mutation.type === 'selection') {
if (this.node.isLeaf) {
return true
}
// ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {
// if (mutation.type === 'selection') {
// if (this.node.isLeaf) {
// return true
// }
return false
}
// return false
// }
if (!this.contentDOM) {
return true
}
// if (!this.contentDOM) {
// return true
// }
const contentDOMHasChanged = !this.contentDOM.contains(mutation.target)
|| this.contentDOM === mutation.target
// const contentDOMHasChanged = !this.contentDOM.contains(mutation.target)
// || this.contentDOM === mutation.target
return contentDOMHasChanged
}
// return contentDOMHasChanged
// }
destroy() {
this.renderer.destroy()
}
// destroy() {
// this.renderer.destroy()
// }
update(node: ProseMirrorNode, decorations: Decoration[]) {
if (typeof this.options.update === 'function') {
return this.options.update(node, decorations)
}
// update(node: ProseMirrorNode, decorations: Decoration[]) {
// if (typeof this.options.update === 'function') {
// return this.options.update(node, decorations)
// }
if (node.type !== this.node.type) {
return false
}
// if (node.type !== this.node.type) {
// return false
// }
if (node === this.node && this.decorations === decorations) {
return true
}
// if (node === this.node && this.decorations === decorations) {
// return true
// }
this.node = node
this.decorations = decorations
// this.renderer.updateProps({ node, decorations })
this.renderer.render()
// this.node = node
// this.decorations = decorations
// // this.renderer.updateProps({ node, decorations })
// this.renderer.render()
return true
}
}
// return true
// }
// }
export function ReactNodeViewRenderer(component: any, options?: Partial<ReactNodeViewRendererOptions>): NodeViewRenderer {
return (props: NodeViewRendererProps) => {
// try to get the parent component
// this is important for vue devtools to show the component hierarchy correctly
// maybe its `undefined` because <editor-content> isnt rendered yet
if (!(props.editor as Editor).contentComponent) {
return {}
}
// export function ReactNodeViewRenderer(component: any, options?: Partial<ReactNodeViewRendererOptions>): NodeViewRenderer {
// return (props: NodeViewRendererProps) => {
// // try to get the parent component
// // this is important for vue devtools to show the component hierarchy correctly
// // maybe its `undefined` because <editor-content> isnt rendered yet
// if (!(props.editor as Editor).contentComponent) {
// return {}
// }
return new ReactNodeView(component, props, options) as NodeView
}
}
// return new ReactNodeView(component, props, options) as NodeView
// }
// }