tiptap/packages/vue-3/src/EditorContent.ts

122 lines
2.3 KiB
TypeScript
Raw Normal View History

2021-02-28 06:56:08 +08:00
import {
DefineComponent,
defineComponent,
getCurrentInstance,
2021-02-28 06:56:08 +08:00
h,
nextTick,
onBeforeUnmount,
PropType,
2021-02-28 06:56:08 +08:00
Ref,
ref,
2021-02-28 06:56:08 +08:00
Teleport,
unref,
2021-02-28 06:56:08 +08:00
watchEffect,
} from 'vue'
import { Editor } from './Editor.js'
2021-02-28 06:56:08 +08:00
export const EditorContent = defineComponent({
name: 'EditorContent',
props: {
editor: {
default: null,
type: Object as PropType<Editor>,
},
},
setup(props) {
const rootEl: Ref<Element | undefined> = ref()
const instance = getCurrentInstance()
watchEffect(() => {
const editor = props.editor
if (editor && editor.options.element && rootEl.value) {
nextTick(() => {
if (!rootEl.value || !editor.options.element.firstChild) {
return
}
2021-03-05 18:01:26 +08:00
const element = unref(rootEl.value)
2021-02-28 06:56:08 +08:00
rootEl.value.append(...editor.options.element.childNodes)
2021-02-28 06:56:08 +08:00
// @ts-ignore
editor.contentComponent = instance.ctx._
editor.setOptions({
2021-03-05 18:01:26 +08:00
element,
2021-02-28 06:56:08 +08:00
})
editor.createNodeViews()
})
}
})
onBeforeUnmount(() => {
const editor = props.editor
if (!editor) {
return
}
2021-02-28 06:56:08 +08:00
// destroy nodeviews before vue removes dom element
2021-03-05 17:20:17 +08:00
if (!editor.isDestroyed) {
2021-02-28 06:56:08 +08:00
editor.view.setProps({
nodeViews: {},
})
}
editor.contentComponent = null
if (!editor.options.element.firstChild) {
return
}
2021-03-05 18:01:26 +08:00
const newElement = document.createElement('div')
2021-02-28 06:56:08 +08:00
newElement.append(...editor.options.element.childNodes)
2021-02-28 06:56:08 +08:00
editor.setOptions({
2021-03-05 18:01:26 +08:00
element: newElement,
2021-02-28 06:56:08 +08:00
})
})
return { rootEl }
},
render() {
const vueRenderers: any[] = []
if (this.editor) {
this.editor.vueRenderers.forEach(vueRenderer => {
const node = h(
Teleport,
{
to: vueRenderer.teleportElement,
key: vueRenderer.id,
},
h(
vueRenderer.component as DefineComponent,
{
ref: vueRenderer.id,
...vueRenderer.props,
},
),
)
vueRenderers.push(node)
})
}
return h(
'div',
{
ref: (el: any) => { this.rootEl = el },
},
...vueRenderers,
)
},
})