tiptap: Dragging a Custom Node creates a duplicate
I created a custom Image Node (with a Vue Component) to be able to create resizable images. It all works fine, but when dragging / moving the image to another location in the document it creates a duplicate instead of moving the original…
`import {Node, Plugin} from ‘tiptap’; import ResizableImageComponent from ‘@/components/Editor/ResizableImageComponent.vue’;
export default class ResizableImage extends Node { public get name() { return ‘resizableImage’; }
public get schema() {
return {
attrs: {
src: {
default: null,
},
width: {
default: '400px',
},
},
group: 'inline',
inline: true,
draggable: true,
selectable: false,
// parseDOM and toDOM is still required to make copy and paste work
parseDOM: [{
tag: 'img',
getAttrs: (dom: any) => ({
src: dom.getAttribute('src'),
width: dom.getAttribute('width'),
}),
}],
toDOM: (node: any) => ['img', {
src: node.attrs.src,
width: node.attrs.width,
}],
};
}
public commands({type}: { type: any }) {
return (attrs: any) => (state: any, dispatch: any) => {
const {selection} = state;
const position = selection.$cursor ? selection.$cursor.pos : selection.$to.pos;
const node = type.create(attrs);
const transaction = state.tr.insert(position, node);
dispatch(transaction);
};
}
public get plugins() {
return [
new Plugin({
props: {
handleDOMEvents: {
drop(view: any, event: any) {
const hasFiles = event.dataTransfer
&& event.dataTransfer.files
&& event.dataTransfer.files.length;
if (!hasFiles) {
return;
}
const images = (Array
.from(event.dataTransfer.files) as File[])
.filter((file) => (/image/i).test(file.type));
if (images.length === 0) {
return;
}
event.preventDefault();
const {schema} = view.state;
const coordinates = view.posAtCoords({left: event.clientX, top: event.clientY});
images.forEach((image) => {
const reader = new FileReader();
reader.onload = (readerEvent) => {
const node = schema.nodes.resizableImage.create({
src: (readerEvent.target as any).result,
});
const transaction = view.state.tr.insert(coordinates.pos, node);
// noinspection JSIgnoredPromiseFromCall
view.dispatch(transaction);
};
reader.readAsDataURL(image);
});
},
},
},
}),
];
}
// return a vue component
// this can be an object or an imported component
public get view() {
return ResizableImageComponent;
}
}
`
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 15 (2 by maintainers)
The provided codesandbox doesn’t work at all for me. Probably it’s too old. I’m closing this here for now.