some more tests

This commit is contained in:
Philipp Kühn
2020-11-19 21:00:24 +01:00
parent 2d2ffb60ef
commit 7f0f29742c
3 changed files with 124 additions and 13 deletions

View File

@@ -4,10 +4,21 @@
<button @click="editor.chain().focus().insertText('hey').run()"> <button @click="editor.chain().focus().insertText('hey').run()">
button button
</button> </button>
<component :is="inner" /> <div>
attrs {{ node.attrs }}
</div>
<inner /> <inner />
</div> --> </div> -->
<inner as="p" class="hey" foo="bar" /> <!-- <inner /> -->
<div style="white-space: normal;">
<button @click="toggleChecked">
toggle checked
</button>
hey {{ node.attrs.checked }}
<inner />
</div>
<!-- <inner as="p" :class="random" foo="bar" /> -->
<!-- <component :is="inner" as="p" /> --> <!-- <component :is="inner" as="p" /> -->
</template> </template>
@@ -19,19 +30,44 @@ export default {
required: true, required: true,
}, },
node: {
type: Object,
required: true,
},
inner: { inner: {
type: [Object, Function], type: [Object, Function],
required: true, required: true,
}, },
updateAttrs: {
type: Function,
required: true,
},
}, },
data() { data() {
return { return {
foo: 'foo', random: 'foo',
} }
}, },
methods: {
toggleChecked() {
this.editor.commands.focus()
this.updateAttrs({
checked: !this.node.attrs.checked,
})
},
},
mounted() { mounted() {
// console.log(this.node)
console.log('mounted')
// setInterval(() => {
// this.random = `foo${Math.random()}`
// }, 1000)
// console.log(this) // console.log(this)
}, },
} }

View File

@@ -1,4 +1,4 @@
import { Node } from '@tiptap/core' import { Node, mergeAttributes } from '@tiptap/core'
import { VueRenderer } from '@tiptap/vue' import { VueRenderer } from '@tiptap/vue'
import Component from './Component.vue' import Component from './Component.vue'
@@ -13,6 +13,16 @@ export default Node.create({
selectable: false, selectable: false,
// atom: true,
addAttributes() {
return {
checked: {
default: false,
},
}
},
parseHTML() { parseHTML() {
return [ return [
{ {
@@ -21,8 +31,8 @@ export default Node.create({
] ]
}, },
renderHTML() { renderHTML({ HTMLAttributes }) {
return ['div', { 'data-type': 'test' }, 0] return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'test' }), 0]
}, },
addNodeView() { addNodeView() {

View File

@@ -1,5 +1,5 @@
import { Editor, Node, NodeViewRendererProps } from '@tiptap/core' import { Editor, Node, NodeViewRendererProps } from '@tiptap/core'
import { NodeView } from 'prosemirror-view' import { Decoration, NodeView } from 'prosemirror-view'
import { import {
Node as ProseMirrorNode, Node as ProseMirrorNode,
@@ -20,18 +20,17 @@ class VueNodeView implements NodeView {
node!: ProseMirrorNode node!: ProseMirrorNode
decorations!: Decoration[]
id!: string id!: string
constructor(component: Vue | VueConstructor, props: NodeViewRendererProps) { getPos!: any
// eslint-disable-next-line
const { node, editor, getPos } = props
// eslint-disable-next-line
const { view } = editor
constructor(component: Vue | VueConstructor, props: NodeViewRendererProps) {
this.editor = props.editor this.editor = props.editor
this.extension = props.extension this.extension = props.extension
this.node = props.node this.node = props.node
this.getPos = props.getPos
this.mount(component) this.mount(component)
} }
@@ -52,11 +51,13 @@ class VueNodeView implements NodeView {
render(createElement, context) { render(createElement, context) {
return createElement( return createElement(
context.props.as, { context.props.as, {
// this.as, {
style: { style: {
whiteSpace: 'pre-wrap', whiteSpace: 'pre-wrap',
}, },
attrs: { attrs: {
id, id,
// contenteditable: true,
}, },
}, },
) )
@@ -74,6 +75,8 @@ class VueNodeView implements NodeView {
const props = { const props = {
editor: this.editor, editor: this.editor,
inner: Inner, inner: Inner,
node: this.node,
updateAttrs: (attrs: {}) => this.updateAttrs(attrs),
} }
this.vm = new Component({ this.vm = new Component({
@@ -95,6 +98,8 @@ class VueNodeView implements NodeView {
} }
stopEvent(event: Event): boolean { stopEvent(event: Event): boolean {
// console.log(event.type)
const isDraggable = this.node.type.spec.draggable const isDraggable = this.node.type.spec.draggable
const isCopy = event.type === 'copy' const isCopy = event.type === 'copy'
const isPaste = event.type === 'paste' const isPaste = event.type === 'paste'
@@ -108,6 +113,66 @@ class VueNodeView implements NodeView {
return true return true
} }
ignoreMutation(mutation: MutationRecord | { type: 'selection'; target: Element }) {
// return false
// if (mutation.type === 'selection') {
// console.log({ mutation })
// return true
// }
// return true
// console.log({ mutation })
if (!this.contentDOM) {
return true
}
return !this.contentDOM.contains(mutation.target)
}
update(node: ProseMirrorNode, decorations: Decoration[]) {
if (node.type !== this.node.type) {
return false
}
if (node === this.node && this.decorations === decorations) {
return true
}
this.node = node
this.decorations = decorations
this.updateComponentProps()
return true
}
updateComponentProps() {
this.vm.$props.node = this.node
this.vm.$props.decorations = this.decorations
}
updateAttrs(attrs: {}) {
if (!this.editor.view.editable) {
return
}
const { state } = this.editor.view
// const { type } = this.node
const pos = this.getPos()
const newAttrs = {
...this.node.attrs,
...attrs,
}
// const transaction = this.isMark
// ? state.tr
// .removeMark(pos.from, pos.to, type)
// .addMark(pos.from, pos.to, type.create(newAttrs))
// : state.tr.setNodeMarkup(pos, null, newAttrs)
const transaction = state.tr.setNodeMarkup(pos, undefined, newAttrs)
this.editor.view.dispatch(transaction)
}
} }
export default function VueRenderer(component: Vue | VueConstructor) { export default function VueRenderer(component: Vue | VueConstructor) {