mirror of https://github.com/fantasticit/think.git
improve dragable
This commit is contained in:
parent
87bccec882
commit
d0411a03da
|
@ -1,8 +1,8 @@
|
||||||
import { Extension } from '@tiptap/core';
|
import { Extension } from '@tiptap/core';
|
||||||
import { Plugin, PluginKey, Selection } from 'prosemirror-state';
|
import { Plugin, PluginKey, Selection } from 'prosemirror-state';
|
||||||
import { NodeSelection } from 'prosemirror-state';
|
import { NodeSelection, TextSelection } from 'prosemirror-state';
|
||||||
import { __serializeForClipboard, EditorView } from 'prosemirror-view';
|
import { __serializeForClipboard, EditorView } from 'prosemirror-view';
|
||||||
import { ActiveNode, getNodeAtPos, removePossibleTable, selectRootNodeByDom } from 'tiptap/prose-utils';
|
import { ActiveNode, getNodeAtPos, removePossibleTable, safePos, selectRootNodeByDom } from 'tiptap/prose-utils';
|
||||||
|
|
||||||
export const DragablePluginKey = new PluginKey('dragable');
|
export const DragablePluginKey = new PluginKey('dragable');
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ export const Dragable = Extension.create({
|
||||||
let activeNode: ActiveNode;
|
let activeNode: ActiveNode;
|
||||||
let activeSelection: Selection;
|
let activeSelection: Selection;
|
||||||
let dragging = false;
|
let dragging = false;
|
||||||
|
let mouseleaveTimer = null;
|
||||||
|
|
||||||
const createDragHandleDOM = () => {
|
const createDragHandleDOM = () => {
|
||||||
const dom = document.createElement('div');
|
const dom = document.createElement('div');
|
||||||
|
@ -51,6 +52,18 @@ export const Dragable = Extension.create({
|
||||||
showDragHandleDOM();
|
showDragHandleDOM();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleMouseEnter = () => {
|
||||||
|
if (!activeNode) return null;
|
||||||
|
|
||||||
|
clearTimeout(mouseleaveTimer);
|
||||||
|
showDragHandleDOM();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleMouseLeave = () => {
|
||||||
|
if (!activeNode) return null;
|
||||||
|
hideDragHandleDOM();
|
||||||
|
};
|
||||||
|
|
||||||
const handleMouseDown = () => {
|
const handleMouseDown = () => {
|
||||||
if (!activeNode) return null;
|
if (!activeNode) return null;
|
||||||
|
|
||||||
|
@ -75,13 +88,14 @@ export const Dragable = Extension.create({
|
||||||
const handleDragStart = (event) => {
|
const handleDragStart = (event) => {
|
||||||
dragging = true;
|
dragging = true;
|
||||||
if (event.dataTransfer && activeSelection) {
|
if (event.dataTransfer && activeSelection) {
|
||||||
const brokenClipboardAPI = false;
|
|
||||||
const slice = activeSelection.content();
|
const slice = activeSelection.content();
|
||||||
event.dataTransfer.effectAllowed = 'copyMove';
|
event.dataTransfer.effectAllowed = 'copyMove';
|
||||||
const { dom, text } = __serializeForClipboard(editorView, slice);
|
const { dom, text } = __serializeForClipboard(editorView, slice);
|
||||||
event.dataTransfer.clearData();
|
event.dataTransfer.clearData();
|
||||||
event.dataTransfer.setData(brokenClipboardAPI ? 'Text' : 'text/html', dom.innerHTML);
|
event.dataTransfer.setData('text/html', dom.innerHTML);
|
||||||
if (!brokenClipboardAPI) event.dataTransfer.setData('text/plain', text);
|
event.dataTransfer.setData('text/plain', text);
|
||||||
|
event.dataTransfer.setDragImage(activeNode?.el as any, 0, 0);
|
||||||
|
|
||||||
editorView.dragging = {
|
editorView.dragging = {
|
||||||
slice,
|
slice,
|
||||||
move: true,
|
move: true,
|
||||||
|
@ -95,6 +109,8 @@ export const Dragable = Extension.create({
|
||||||
view: (view) => {
|
view: (view) => {
|
||||||
if (view.editable) {
|
if (view.editable) {
|
||||||
dragHandleDOM = createDragHandleDOM();
|
dragHandleDOM = createDragHandleDOM();
|
||||||
|
dragHandleDOM.addEventListener('mouseenter', handleMouseEnter);
|
||||||
|
dragHandleDOM.addEventListener('mouseleave', handleMouseLeave);
|
||||||
dragHandleDOM.addEventListener('mousedown', handleMouseDown);
|
dragHandleDOM.addEventListener('mousedown', handleMouseDown);
|
||||||
dragHandleDOM.addEventListener('mouseup', handleMouseUp);
|
dragHandleDOM.addEventListener('mouseup', handleMouseUp);
|
||||||
dragHandleDOM.addEventListener('dragstart', handleDragStart);
|
dragHandleDOM.addEventListener('dragstart', handleDragStart);
|
||||||
|
@ -108,6 +124,8 @@ export const Dragable = Extension.create({
|
||||||
destroy: () => {
|
destroy: () => {
|
||||||
if (!dragHandleDOM) return;
|
if (!dragHandleDOM) return;
|
||||||
|
|
||||||
|
dragHandleDOM.removeEventListener('mouseenter', handleMouseEnter);
|
||||||
|
dragHandleDOM.removeEventListener('mouseleave', handleMouseLeave);
|
||||||
dragHandleDOM.removeEventListener('mousedown', handleMouseDown);
|
dragHandleDOM.removeEventListener('mousedown', handleMouseDown);
|
||||||
dragHandleDOM.removeEventListener('mouseup', handleMouseUp);
|
dragHandleDOM.removeEventListener('mouseup', handleMouseUp);
|
||||||
dragHandleDOM.removeEventListener('dragstart', handleDragStart);
|
dragHandleDOM.removeEventListener('dragstart', handleDragStart);
|
||||||
|
@ -125,6 +143,26 @@ export const Dragable = Extension.create({
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
if (activeSelection) {
|
||||||
|
[
|
||||||
|
'ProseMirror-selectednode',
|
||||||
|
'ProseMirror-selectedblocknode-dragable',
|
||||||
|
'ProseMirror-selectedblocknode-normal',
|
||||||
|
].forEach((cls) => {
|
||||||
|
(view.dom as HTMLElement).querySelectorAll(`.${cls}`).forEach((dom) => dom.classList.remove(cls));
|
||||||
|
});
|
||||||
|
const noneSelection = new TextSelection(
|
||||||
|
view.state.doc.resolve(safePos(view.state, eventPos?.pos ?? 0))
|
||||||
|
);
|
||||||
|
view.dispatch(view.state.tr.setSelection(noneSelection));
|
||||||
|
this.editor.commands.blur();
|
||||||
|
|
||||||
|
activeSelection = null;
|
||||||
|
activeNode = null;
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
|
||||||
const $mouse = view.state.doc.resolve(eventPos.pos);
|
const $mouse = view.state.doc.resolve(eventPos.pos);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -196,6 +234,13 @@ export const Dragable = Extension.create({
|
||||||
renderDragHandleDOM(view, result.el);
|
renderDragHandleDOM(view, result.el);
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
mouseleave: () => {
|
||||||
|
clearTimeout(mouseleaveTimer);
|
||||||
|
mouseleaveTimer = setTimeout(() => {
|
||||||
|
hideDragHandleDOM();
|
||||||
|
}, 400);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
keydown: () => {
|
keydown: () => {
|
||||||
if (!editorView.editable || !dragHandleDOM) return false;
|
if (!editorView.editable || !dragHandleDOM) return false;
|
||||||
hideDragHandleDOM();
|
hideDragHandleDOM();
|
||||||
|
|
Loading…
Reference in New Issue