set parent component for vue node views
This commit is contained in:
@@ -31,6 +31,8 @@ import * as d3 from 'd3'
|
|||||||
import simplify from 'simplify-js'
|
import simplify from 'simplify-js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'Paper',
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
updateAttributes: {
|
updateAttributes: {
|
||||||
type: Function,
|
type: Function,
|
||||||
|
|||||||
@@ -252,9 +252,7 @@ export class Editor extends EventEmitter {
|
|||||||
|
|
||||||
this.view.updateState(newState)
|
this.view.updateState(newState)
|
||||||
|
|
||||||
this.view.setProps({
|
this.createNodeViews()
|
||||||
nodeViews: this.extensionManager.nodeViews,
|
|
||||||
})
|
|
||||||
|
|
||||||
// Let’s store the editor instance in the DOM element.
|
// Let’s store the editor instance in the DOM element.
|
||||||
// So we’ll have access to it for tests.
|
// So we’ll have access to it for tests.
|
||||||
@@ -262,6 +260,15 @@ export class Editor extends EventEmitter {
|
|||||||
dom.editor = this.proxy
|
dom.editor = this.proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates all node views.
|
||||||
|
*/
|
||||||
|
public createNodeViews() {
|
||||||
|
this.view.setProps({
|
||||||
|
nodeViews: this.extensionManager.nodeViews,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a ProseMirror document.
|
* Creates a ProseMirror document.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,6 +5,12 @@ import { Node as ProseMirrorNode } from 'prosemirror-model'
|
|||||||
import Vue from 'vue'
|
import Vue from 'vue'
|
||||||
import { VueConstructor } from 'vue/types/umd'
|
import { VueConstructor } from 'vue/types/umd'
|
||||||
|
|
||||||
|
function getComponentFromElement(element: HTMLElement): Vue {
|
||||||
|
// @ts-ignore
|
||||||
|
// eslint-disable-next-line
|
||||||
|
return element.__vue__
|
||||||
|
}
|
||||||
|
|
||||||
interface VueRendererOptions {
|
interface VueRendererOptions {
|
||||||
stopEvent: ((event: Event) => boolean) | null,
|
stopEvent: ((event: Event) => boolean) | null,
|
||||||
update: ((node: ProseMirrorNode, decorations: Decoration[]) => boolean) | null,
|
update: ((node: ProseMirrorNode, decorations: Decoration[]) => boolean) | null,
|
||||||
@@ -132,7 +138,7 @@ class VueNodeView implements NodeView {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = {
|
const propsData = {
|
||||||
NodeViewWrapper,
|
NodeViewWrapper,
|
||||||
NodeViewContent,
|
NodeViewContent,
|
||||||
editor: this.editor,
|
editor: this.editor,
|
||||||
@@ -144,10 +150,13 @@ class VueNodeView implements NodeView {
|
|||||||
updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
|
updateAttributes: (attributes = {}) => this.updateAttributes(attributes),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const parent = this.editor.view.dom.parentElement
|
||||||
|
? getComponentFromElement(this.editor.view.dom.parentElement)
|
||||||
|
: undefined
|
||||||
|
|
||||||
this.vm = new Component({
|
this.vm = new Component({
|
||||||
// TODO: get parent component <editor-content>
|
parent,
|
||||||
// parent: this.parent,
|
propsData,
|
||||||
propsData: props,
|
|
||||||
}).$mount()
|
}).$mount()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,11 +267,17 @@ class VueNodeView implements NodeView {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// prevents `Avoid mutating a prop directly` error message
|
||||||
|
const originalSilent = Vue.config.silent
|
||||||
|
Vue.config.silent = true
|
||||||
|
|
||||||
Object
|
Object
|
||||||
.entries(data)
|
.entries(data)
|
||||||
.forEach(([key, value]) => {
|
.forEach(([key, value]) => {
|
||||||
this.vm.$props[key] = value
|
this.vm.$props[key] = value
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Vue.config.silent = originalSilent
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAttributes(attributes: {}) {
|
updateAttributes(attributes: {}) {
|
||||||
@@ -295,5 +310,18 @@ class VueNodeView implements NodeView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function VueRenderer(component: Vue | VueConstructor, options?: Partial<VueRendererOptions>) {
|
export default function VueRenderer(component: Vue | VueConstructor, options?: Partial<VueRendererOptions>) {
|
||||||
return (props: NodeViewRendererProps) => new VueNodeView(component, props, options) as NodeView
|
return (props: NodeViewRendererProps) => {
|
||||||
|
// try to get the parent component
|
||||||
|
// this is important for vue devtools to show the component hierarchy correctly
|
||||||
|
// maybe it’s `undefined` because <editor-content> isn’t rendered yet
|
||||||
|
const parent = props.editor.view.dom.parentElement
|
||||||
|
? getComponentFromElement(props.editor.view.dom.parentElement)
|
||||||
|
: undefined
|
||||||
|
|
||||||
|
if (!parent) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
return new VueNodeView(component, props, options) as NodeView
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export default Vue.extend({
|
|||||||
if (editor && editor.options.element) {
|
if (editor && editor.options.element) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.$el.appendChild(editor.options.element.firstChild)
|
this.$el.appendChild(editor.options.element.firstChild)
|
||||||
// editor.setParentComponent(this)
|
editor.createNodeViews()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user