From b8886fa4085d90cf187c1834e29f60b925f5687b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20Ku=CC=88hn?= Date: Wed, 18 Nov 2020 22:50:07 +0100 Subject: [PATCH] add node view playground --- docs/src/components/Demo/index.vue | 2 +- .../src/demos/Examples/NodeView/Component.vue | 15 +++++ docs/src/demos/Examples/NodeView/Test.ts | 29 +++++++++ docs/src/demos/Examples/NodeView/index.vue | 65 +++++++++++++++++++ docs/src/docPages/examples/node-view.md | 3 + packages/core/src/ExtensionManager.ts | 1 + packages/core/src/types.ts | 1 + packages/vue/src/VueRenderer.ts | 25 ++++++- 8 files changed, 138 insertions(+), 3 deletions(-) create mode 100644 docs/src/demos/Examples/NodeView/Component.vue create mode 100644 docs/src/demos/Examples/NodeView/Test.ts create mode 100644 docs/src/demos/Examples/NodeView/index.vue create mode 100644 docs/src/docPages/examples/node-view.md diff --git a/docs/src/components/Demo/index.vue b/docs/src/components/Demo/index.vue index b1c888c5..ce7aaf05 100644 --- a/docs/src/components/Demo/index.vue +++ b/docs/src/components/Demo/index.vue @@ -120,7 +120,7 @@ export default { } }) .filter(item => { - return ['vue', 'jsx', 'scss'].includes(item.extension) + return ['vue', 'ts', 'jsx', 'scss'].includes(item.extension) }) .sortBy(item => item.path.split('/').length && !item.path.endsWith('index.vue')) .toArray() diff --git a/docs/src/demos/Examples/NodeView/Component.vue b/docs/src/demos/Examples/NodeView/Component.vue new file mode 100644 index 00000000..0d99908c --- /dev/null +++ b/docs/src/demos/Examples/NodeView/Component.vue @@ -0,0 +1,15 @@ + + + + + diff --git a/docs/src/demos/Examples/NodeView/Test.ts b/docs/src/demos/Examples/NodeView/Test.ts new file mode 100644 index 00000000..13fae1f8 --- /dev/null +++ b/docs/src/demos/Examples/NodeView/Test.ts @@ -0,0 +1,29 @@ +import { Node } from '@tiptap/core' +import { VueRenderer } from '@tiptap/vue' +import Component from './Component.vue' + +export default Node.create({ + name: 'test', + + group: 'block', + + draggable: true, + + selectable: false, + + parseHTML() { + return [ + { + tag: 'div[data-type="test"]', + }, + ] + }, + + renderHTML() { + return ['div', { 'data-type': 'test' }] + }, + + addNodeView() { + return VueRenderer(Component) + }, +}) diff --git a/docs/src/demos/Examples/NodeView/index.vue b/docs/src/demos/Examples/NodeView/index.vue new file mode 100644 index 00000000..9103e856 --- /dev/null +++ b/docs/src/demos/Examples/NodeView/index.vue @@ -0,0 +1,65 @@ + + + + + diff --git a/docs/src/docPages/examples/node-view.md b/docs/src/docPages/examples/node-view.md new file mode 100644 index 00000000..1040abeb --- /dev/null +++ b/docs/src/docPages/examples/node-view.md @@ -0,0 +1,3 @@ +# Node View + + diff --git a/packages/core/src/ExtensionManager.ts b/packages/core/src/ExtensionManager.ts index eb10635a..eccb2b37 100644 --- a/packages/core/src/ExtensionManager.ts +++ b/packages/core/src/ExtensionManager.ts @@ -130,6 +130,7 @@ export default class ExtensionManager { getPos, decorations, HTMLAttributes, + extension, }) } diff --git a/packages/core/src/types.ts b/packages/core/src/types.ts index d2a8727a..a8ed6fee 100644 --- a/packages/core/src/types.ts +++ b/packages/core/src/types.ts @@ -90,6 +90,7 @@ export type NodeViewRendererProps = { getPos: (() => number) | boolean, decorations: Decoration[], HTMLAttributes: { [key: string]: any }, + extension: Node, } export type NodeViewRenderer = (props: NodeViewRendererProps) => NodeView diff --git a/packages/vue/src/VueRenderer.ts b/packages/vue/src/VueRenderer.ts index 60ba426c..e4e489ce 100644 --- a/packages/vue/src/VueRenderer.ts +++ b/packages/vue/src/VueRenderer.ts @@ -1,5 +1,9 @@ -import { NodeViewRendererProps } from '@tiptap/core' +import { Node, NodeViewRendererProps } from '@tiptap/core' import { NodeView } from 'prosemirror-view' + +import { + Node as ProseMirrorNode, +} from 'prosemirror-model' import Vue from 'vue' import { VueConstructor } from 'vue/types/umd' @@ -7,12 +11,19 @@ class VueNodeView implements NodeView { vm!: Vue + extension!: Node + + node!: ProseMirrorNode + constructor(component: Vue | VueConstructor, props: NodeViewRendererProps) { // eslint-disable-next-line const { node, editor, getPos } = props // eslint-disable-next-line const { view } = editor + this.extension = props.extension + this.node = props.node + this.mount(component) } @@ -33,7 +44,17 @@ class VueNodeView implements NodeView { return this.vm.$refs.content as Element } - stopEvent() { + stopEvent(event: Event): boolean { + const isDraggable = this.node.type.spec.draggable + const isCopy = event.type === 'copy' + const isPaste = event.type === 'paste' + const isCut = event.type === 'cut' + const isDrag = event.type.startsWith('drag') || event.type === 'drop' + + if ((isDraggable && isDrag) || isCopy || isPaste || isCut) { + return false + } + return true }