some more tests
This commit is contained in:
@@ -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)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user