@tiptap/extension-drag-handle 2.24.2 → 3.0.0-beta.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +21 -0
- package/dist/index.cjs +463 -457
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +68 -0
- package/dist/index.d.ts +68 -5
- package/dist/index.js +441 -450
- package/dist/index.js.map +1 -1
- package/package.json +20 -18
- package/src/drag-handle-plugin.ts +233 -236
- package/src/drag-handle.ts +42 -28
- package/src/helpers/dragHandler.ts +8 -8
- package/src/helpers/findNextElementFromCursor.ts +3 -5
- package/src/helpers/getInnerCoords.ts +3 -7
- package/src/helpers/getOuterNode.ts +1 -1
- package/dist/drag-handle-plugin.d.ts +0 -20
- package/dist/drag-handle-plugin.d.ts.map +0 -1
- package/dist/drag-handle.d.ts +0 -44
- package/dist/drag-handle.d.ts.map +0 -1
- package/dist/helpers/cloneElement.d.ts +0 -2
- package/dist/helpers/cloneElement.d.ts.map +0 -1
- package/dist/helpers/dragHandler.d.ts +0 -3
- package/dist/helpers/dragHandler.d.ts.map +0 -1
- package/dist/helpers/findNextElementFromCursor.d.ts +0 -14
- package/dist/helpers/findNextElementFromCursor.d.ts.map +0 -1
- package/dist/helpers/getComputedStyle.d.ts +0 -2
- package/dist/helpers/getComputedStyle.d.ts.map +0 -1
- package/dist/helpers/getInnerCoords.d.ts +0 -6
- package/dist/helpers/getInnerCoords.d.ts.map +0 -1
- package/dist/helpers/getOuterNode.d.ts +0 -4
- package/dist/helpers/getOuterNode.d.ts.map +0 -1
- package/dist/helpers/minMax.d.ts +0 -2
- package/dist/helpers/minMax.d.ts.map +0 -1
- package/dist/helpers/removeNode.d.ts +0 -2
- package/dist/helpers/removeNode.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.umd.js +0 -499
- package/dist/index.umd.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,504 +1,510 @@
|
|
|
1
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
2
19
|
|
|
3
|
-
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
DragHandle: () => DragHandle,
|
|
24
|
+
DragHandlePlugin: () => DragHandlePlugin,
|
|
25
|
+
default: () => index_default,
|
|
26
|
+
defaultComputePositionConfig: () => defaultComputePositionConfig,
|
|
27
|
+
dragHandlePluginDefaultKey: () => dragHandlePluginDefaultKey
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
4
30
|
|
|
5
|
-
|
|
6
|
-
var
|
|
7
|
-
var state = require('@tiptap/pm/state');
|
|
8
|
-
var tippy = require('tippy.js');
|
|
9
|
-
var yProsemirror = require('y-prosemirror');
|
|
10
|
-
var extensionNodeRange = require('@tiptap/extension-node-range');
|
|
31
|
+
// src/drag-handle.ts
|
|
32
|
+
var import_core = require("@tiptap/core");
|
|
11
33
|
|
|
12
|
-
|
|
34
|
+
// src/drag-handle-plugin.ts
|
|
35
|
+
var import_dom = require("@floating-ui/dom");
|
|
36
|
+
var import_extension_collaboration = require("@tiptap/extension-collaboration");
|
|
37
|
+
var import_state = require("@tiptap/pm/state");
|
|
38
|
+
var import_y_tiptap = require("@tiptap/y-tiptap");
|
|
13
39
|
|
|
14
|
-
|
|
40
|
+
// src/helpers/dragHandler.ts
|
|
41
|
+
var import_extension_node_range = require("@tiptap/extension-node-range");
|
|
15
42
|
|
|
43
|
+
// src/helpers/cloneElement.ts
|
|
16
44
|
function getCSSText(element) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
45
|
+
let value = "";
|
|
46
|
+
const style = getComputedStyle(element);
|
|
47
|
+
for (let i = 0; i < style.length; i += 1) {
|
|
48
|
+
value += `${style[i]}:${style.getPropertyValue(style[i])};`;
|
|
49
|
+
}
|
|
50
|
+
return value;
|
|
23
51
|
}
|
|
24
52
|
function cloneElement(node) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
53
|
+
const clonedNode = node.cloneNode(true);
|
|
54
|
+
const sourceElements = [node, ...Array.from(node.getElementsByTagName("*"))];
|
|
55
|
+
const targetElements = [clonedNode, ...Array.from(clonedNode.getElementsByTagName("*"))];
|
|
56
|
+
sourceElements.forEach((sourceElement, index) => {
|
|
57
|
+
targetElements[index].style.cssText = getCSSText(sourceElement);
|
|
58
|
+
});
|
|
59
|
+
return clonedNode;
|
|
32
60
|
}
|
|
33
61
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
if (!resultNode) {
|
|
54
|
-
resultNode = editor.state.doc.nodeAt(Math.max(pos, 0));
|
|
55
|
-
}
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
if (direction === 'left') {
|
|
60
|
-
currentX -= 1;
|
|
62
|
+
// src/helpers/findNextElementFromCursor.ts
|
|
63
|
+
var findElementNextToCoords = (options) => {
|
|
64
|
+
const { x, y, direction, editor } = options;
|
|
65
|
+
let resultElement = null;
|
|
66
|
+
let resultNode = null;
|
|
67
|
+
let pos = null;
|
|
68
|
+
let currentX = x;
|
|
69
|
+
while (resultNode === null && currentX < window.innerWidth && currentX > 0) {
|
|
70
|
+
const allElements = document.elementsFromPoint(currentX, y);
|
|
71
|
+
const prosemirrorIndex = allElements.findIndex((element) => element.classList.contains("ProseMirror"));
|
|
72
|
+
const filteredElements = allElements.slice(0, prosemirrorIndex);
|
|
73
|
+
if (filteredElements.length > 0) {
|
|
74
|
+
const target = filteredElements[0];
|
|
75
|
+
resultElement = target;
|
|
76
|
+
pos = editor.view.posAtDOM(target, 0);
|
|
77
|
+
if (pos >= 0) {
|
|
78
|
+
resultNode = editor.state.doc.nodeAt(Math.max(pos - 1, 0));
|
|
79
|
+
if (resultNode == null ? void 0 : resultNode.isText) {
|
|
80
|
+
resultNode = editor.state.doc.nodeAt(Math.max(pos - 1, 0));
|
|
61
81
|
}
|
|
62
|
-
|
|
63
|
-
|
|
82
|
+
if (!resultNode) {
|
|
83
|
+
resultNode = editor.state.doc.nodeAt(Math.max(pos, 0));
|
|
64
84
|
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
65
87
|
}
|
|
66
|
-
|
|
88
|
+
if (direction === "left") {
|
|
89
|
+
currentX -= 1;
|
|
90
|
+
} else {
|
|
91
|
+
currentX += 1;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return { resultElement, resultNode, pos: pos != null ? pos : null };
|
|
67
95
|
};
|
|
68
96
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
97
|
+
// src/helpers/getComputedStyle.ts
|
|
98
|
+
function getComputedStyle2(node, property) {
|
|
99
|
+
const style = window.getComputedStyle(node);
|
|
100
|
+
return style[property];
|
|
72
101
|
}
|
|
73
102
|
|
|
103
|
+
// src/helpers/minMax.ts
|
|
74
104
|
function minMax(value = 0, min = 0, max = 0) {
|
|
75
|
-
|
|
105
|
+
return Math.min(Math.max(value, min), max);
|
|
76
106
|
}
|
|
77
107
|
|
|
108
|
+
// src/helpers/getInnerCoords.ts
|
|
78
109
|
function getInnerCoords(view, x, y) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
110
|
+
const paddingLeft = parseInt(getComputedStyle2(view.dom, "paddingLeft"), 10);
|
|
111
|
+
const paddingRight = parseInt(getComputedStyle2(view.dom, "paddingRight"), 10);
|
|
112
|
+
const borderLeft = parseInt(getComputedStyle2(view.dom, "borderLeftWidth"), 10);
|
|
113
|
+
const borderRight = parseInt(getComputedStyle2(view.dom, "borderLeftWidth"), 10);
|
|
114
|
+
const bounds = view.dom.getBoundingClientRect();
|
|
115
|
+
const coords = {
|
|
116
|
+
left: minMax(x, bounds.left + paddingLeft + borderLeft, bounds.right - paddingRight - borderRight),
|
|
117
|
+
top: y
|
|
118
|
+
};
|
|
119
|
+
return coords;
|
|
89
120
|
}
|
|
90
121
|
|
|
122
|
+
// src/helpers/removeNode.ts
|
|
91
123
|
function removeNode(node) {
|
|
92
|
-
|
|
93
|
-
|
|
124
|
+
var _a;
|
|
125
|
+
(_a = node.parentNode) == null ? void 0 : _a.removeChild(node);
|
|
94
126
|
}
|
|
95
127
|
|
|
128
|
+
// src/helpers/dragHandler.ts
|
|
96
129
|
function getDragHandleRanges(event, editor) {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
130
|
+
const { doc } = editor.view.state;
|
|
131
|
+
const result = findElementNextToCoords({
|
|
132
|
+
editor,
|
|
133
|
+
x: event.clientX,
|
|
134
|
+
y: event.clientY,
|
|
135
|
+
direction: "right"
|
|
136
|
+
});
|
|
137
|
+
if (!result.resultNode || result.pos === null) {
|
|
138
|
+
return [];
|
|
139
|
+
}
|
|
140
|
+
const x = event.clientX;
|
|
141
|
+
const coords = getInnerCoords(editor.view, x, event.clientY);
|
|
142
|
+
const posAtCoords = editor.view.posAtCoords(coords);
|
|
143
|
+
if (!posAtCoords) {
|
|
144
|
+
return [];
|
|
145
|
+
}
|
|
146
|
+
const { pos } = posAtCoords;
|
|
147
|
+
const nodeAt = doc.resolve(pos).parent;
|
|
148
|
+
if (!nodeAt) {
|
|
149
|
+
return [];
|
|
150
|
+
}
|
|
151
|
+
const $from = doc.resolve(result.pos);
|
|
152
|
+
const $to = doc.resolve(result.pos + 1);
|
|
153
|
+
return (0, import_extension_node_range.getSelectionRanges)($from, $to, 0);
|
|
119
154
|
}
|
|
120
155
|
function dragHandler(event, editor) {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
&& dragHandleRange.$to === range.$to;
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
const ranges = empty || !isDragHandleWithinSelection
|
|
135
|
-
? dragHandleRanges
|
|
136
|
-
: selectionRanges;
|
|
137
|
-
if (!ranges.length) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
const { tr } = view.state;
|
|
141
|
-
const wrapper = document.createElement('div');
|
|
142
|
-
const from = ranges[0].$from.pos;
|
|
143
|
-
const to = ranges[ranges.length - 1].$to.pos;
|
|
144
|
-
const selection = extensionNodeRange.NodeRangeSelection.create(view.state.doc, from, to);
|
|
145
|
-
const slice = selection.content();
|
|
146
|
-
ranges.forEach(range => {
|
|
147
|
-
const element = view.nodeDOM(range.$from.pos);
|
|
148
|
-
const clonedElement = cloneElement(element);
|
|
149
|
-
wrapper.append(clonedElement);
|
|
156
|
+
const { view } = editor;
|
|
157
|
+
if (!event.dataTransfer) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const { empty, $from, $to } = view.state.selection;
|
|
161
|
+
const dragHandleRanges = getDragHandleRanges(event, editor);
|
|
162
|
+
const selectionRanges = (0, import_extension_node_range.getSelectionRanges)($from, $to, 0);
|
|
163
|
+
const isDragHandleWithinSelection = selectionRanges.some((range) => {
|
|
164
|
+
return dragHandleRanges.find((dragHandleRange) => {
|
|
165
|
+
return dragHandleRange.$from === range.$from && dragHandleRange.$to === range.$to;
|
|
150
166
|
});
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
167
|
+
});
|
|
168
|
+
const ranges = empty || !isDragHandleWithinSelection ? dragHandleRanges : selectionRanges;
|
|
169
|
+
if (!ranges.length) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const { tr } = view.state;
|
|
173
|
+
const wrapper = document.createElement("div");
|
|
174
|
+
const from = ranges[0].$from.pos;
|
|
175
|
+
const to = ranges[ranges.length - 1].$to.pos;
|
|
176
|
+
const selection = import_extension_node_range.NodeRangeSelection.create(view.state.doc, from, to);
|
|
177
|
+
const slice = selection.content();
|
|
178
|
+
ranges.forEach((range) => {
|
|
179
|
+
const element = view.nodeDOM(range.$from.pos);
|
|
180
|
+
const clonedElement = cloneElement(element);
|
|
181
|
+
wrapper.append(clonedElement);
|
|
182
|
+
});
|
|
183
|
+
wrapper.style.position = "absolute";
|
|
184
|
+
wrapper.style.top = "-10000px";
|
|
185
|
+
document.body.append(wrapper);
|
|
186
|
+
event.dataTransfer.clearData();
|
|
187
|
+
event.dataTransfer.setDragImage(wrapper, 0, 0);
|
|
188
|
+
view.dragging = { slice, move: true };
|
|
189
|
+
tr.setSelection(selection);
|
|
190
|
+
view.dispatch(tr);
|
|
191
|
+
document.addEventListener("drop", () => removeNode(wrapper), { once: true });
|
|
162
192
|
}
|
|
163
193
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
194
|
+
// src/helpers/getOuterNode.ts
|
|
195
|
+
var getOuterNodePos = (doc, pos) => {
|
|
196
|
+
const resolvedPos = doc.resolve(pos);
|
|
197
|
+
const { depth } = resolvedPos;
|
|
198
|
+
if (depth === 0) {
|
|
199
|
+
return pos;
|
|
200
|
+
}
|
|
201
|
+
const a = resolvedPos.pos - resolvedPos.parentOffset;
|
|
202
|
+
return a - 1;
|
|
172
203
|
};
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
204
|
+
var getOuterNode = (doc, pos) => {
|
|
205
|
+
const node = doc.nodeAt(pos);
|
|
206
|
+
const resolvedPos = doc.resolve(pos);
|
|
207
|
+
let { depth } = resolvedPos;
|
|
208
|
+
let parent = node;
|
|
209
|
+
while (depth > 0) {
|
|
210
|
+
const currentNode = resolvedPos.node(depth);
|
|
211
|
+
depth -= 1;
|
|
212
|
+
if (depth === 0) {
|
|
213
|
+
parent = currentNode;
|
|
184
214
|
}
|
|
185
|
-
|
|
215
|
+
}
|
|
216
|
+
return parent;
|
|
186
217
|
};
|
|
187
218
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
219
|
+
// src/drag-handle-plugin.ts
|
|
220
|
+
var getRelativePos = (state, absolutePos) => {
|
|
221
|
+
const ystate = import_y_tiptap.ySyncPluginKey.getState(state);
|
|
222
|
+
if (!ystate) {
|
|
223
|
+
return null;
|
|
224
|
+
}
|
|
225
|
+
return (0, import_y_tiptap.absolutePositionToRelativePosition)(absolutePos, ystate.type, ystate.binding.mapping);
|
|
194
226
|
};
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
227
|
+
var getAbsolutePos = (state, relativePos) => {
|
|
228
|
+
const ystate = import_y_tiptap.ySyncPluginKey.getState(state);
|
|
229
|
+
if (!ystate) {
|
|
230
|
+
return -1;
|
|
231
|
+
}
|
|
232
|
+
return (0, import_y_tiptap.relativePositionToAbsolutePosition)(ystate.doc, ystate.type, relativePos, ystate.binding.mapping) || 0;
|
|
201
233
|
};
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
break;
|
|
208
|
-
}
|
|
209
|
-
tmpDomNode = tmpDomNode.parentNode;
|
|
234
|
+
var getOuterDomNode = (view, domNode) => {
|
|
235
|
+
let tmpDomNode = domNode;
|
|
236
|
+
while (tmpDomNode == null ? void 0 : tmpDomNode.parentNode) {
|
|
237
|
+
if (tmpDomNode.parentNode === view.dom) {
|
|
238
|
+
break;
|
|
210
239
|
}
|
|
211
|
-
|
|
240
|
+
tmpDomNode = tmpDomNode.parentNode;
|
|
241
|
+
}
|
|
242
|
+
return tmpDomNode;
|
|
212
243
|
};
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
244
|
+
var dragHandlePluginDefaultKey = new import_state.PluginKey("dragHandle");
|
|
245
|
+
var DragHandlePlugin = ({
|
|
246
|
+
pluginKey = dragHandlePluginDefaultKey,
|
|
247
|
+
element,
|
|
248
|
+
editor,
|
|
249
|
+
computePositionConfig,
|
|
250
|
+
onNodeChange
|
|
251
|
+
}) => {
|
|
252
|
+
const wrapper = document.createElement("div");
|
|
253
|
+
let locked = false;
|
|
254
|
+
let currentNode = null;
|
|
255
|
+
let currentNodePos = -1;
|
|
256
|
+
let currentNodeRelPos;
|
|
257
|
+
function hideHandle() {
|
|
258
|
+
if (!element) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
element.style.visibility = "hidden";
|
|
262
|
+
element.style.pointerEvents = "none";
|
|
263
|
+
}
|
|
264
|
+
function showHandle() {
|
|
265
|
+
if (!element) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (!editor.isEditable) {
|
|
269
|
+
hideHandle();
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
element.style.visibility = "";
|
|
273
|
+
element.style.pointerEvents = "auto";
|
|
274
|
+
}
|
|
275
|
+
function repositionDragHandle(dom) {
|
|
276
|
+
const virtualElement = {
|
|
277
|
+
getBoundingClientRect: () => dom.getBoundingClientRect()
|
|
278
|
+
};
|
|
279
|
+
(0, import_dom.computePosition)(virtualElement, element, computePositionConfig).then((val) => {
|
|
280
|
+
Object.assign(element.style, {
|
|
281
|
+
position: val.strategy,
|
|
282
|
+
left: `${val.x}px`,
|
|
283
|
+
top: `${val.y}px`
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
function onDragStart(e) {
|
|
288
|
+
dragHandler(e, editor);
|
|
289
|
+
setTimeout(() => {
|
|
290
|
+
if (element) {
|
|
291
|
+
element.style.pointerEvents = "none";
|
|
292
|
+
}
|
|
293
|
+
}, 0);
|
|
294
|
+
}
|
|
295
|
+
function onDragEnd() {
|
|
296
|
+
hideHandle();
|
|
297
|
+
if (element) {
|
|
298
|
+
element.style.pointerEvents = "auto";
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
element.addEventListener("dragstart", onDragStart);
|
|
302
|
+
element.addEventListener("dragend", onDragEnd);
|
|
303
|
+
wrapper.appendChild(element);
|
|
304
|
+
return {
|
|
305
|
+
unbind() {
|
|
306
|
+
element.removeEventListener("dragstart", onDragStart);
|
|
307
|
+
element.removeEventListener("dragend", onDragEnd);
|
|
308
|
+
},
|
|
309
|
+
plugin: new import_state.Plugin({
|
|
310
|
+
key: typeof pluginKey === "string" ? new import_state.PluginKey(pluginKey) : pluginKey,
|
|
311
|
+
state: {
|
|
312
|
+
init() {
|
|
313
|
+
return { locked: false };
|
|
314
|
+
},
|
|
315
|
+
apply(tr, value, _oldState, state) {
|
|
316
|
+
const isLocked = tr.getMeta("lockDragHandle");
|
|
317
|
+
const hideDragHandle = tr.getMeta("hideDragHandle");
|
|
318
|
+
if (isLocked !== void 0) {
|
|
319
|
+
locked = isLocked;
|
|
320
|
+
}
|
|
321
|
+
if (hideDragHandle) {
|
|
322
|
+
hideHandle();
|
|
323
|
+
locked = false;
|
|
324
|
+
currentNode = null;
|
|
325
|
+
currentNodePos = -1;
|
|
326
|
+
onNodeChange == null ? void 0 : onNodeChange({ editor, node: null, pos: -1 });
|
|
327
|
+
return value;
|
|
328
|
+
}
|
|
329
|
+
if (tr.docChanged && currentNodePos !== -1 && element) {
|
|
330
|
+
if ((0, import_extension_collaboration.isChangeOrigin)(tr)) {
|
|
331
|
+
const newPos = getAbsolutePos(state, currentNodeRelPos);
|
|
332
|
+
if (newPos !== currentNodePos) {
|
|
333
|
+
currentNodePos = newPos;
|
|
334
|
+
}
|
|
335
|
+
} else {
|
|
336
|
+
const newPos = tr.mapping.map(currentNodePos);
|
|
337
|
+
if (newPos !== currentNodePos) {
|
|
338
|
+
currentNodePos = newPos;
|
|
339
|
+
currentNodeRelPos = getRelativePos(state, currentNodePos);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
return value;
|
|
344
|
+
}
|
|
345
|
+
},
|
|
346
|
+
view: (view) => {
|
|
347
|
+
var _a;
|
|
348
|
+
element.draggable = true;
|
|
349
|
+
element.style.pointerEvents = "auto";
|
|
350
|
+
(_a = editor.view.dom.parentElement) == null ? void 0 : _a.appendChild(wrapper);
|
|
351
|
+
wrapper.style.pointerEvents = "none";
|
|
352
|
+
wrapper.style.position = "absolute";
|
|
353
|
+
wrapper.style.top = "0";
|
|
354
|
+
wrapper.style.left = "0";
|
|
355
|
+
return {
|
|
356
|
+
update(_, oldState) {
|
|
357
|
+
if (!element) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (!editor.isEditable) {
|
|
361
|
+
hideHandle();
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
if (locked) {
|
|
365
|
+
element.draggable = false;
|
|
366
|
+
} else {
|
|
367
|
+
element.draggable = true;
|
|
368
|
+
}
|
|
369
|
+
if (view.state.doc.eq(oldState.doc) || currentNodePos === -1) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
let domNode = view.nodeDOM(currentNodePos);
|
|
373
|
+
domNode = getOuterDomNode(view, domNode);
|
|
374
|
+
if (domNode === view.dom) {
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
if ((domNode == null ? void 0 : domNode.nodeType) !== 1) {
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
const domNodePos = view.posAtDOM(domNode, 0);
|
|
381
|
+
const outerNode = getOuterNode(editor.state.doc, domNodePos);
|
|
382
|
+
const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos);
|
|
383
|
+
currentNode = outerNode;
|
|
384
|
+
currentNodePos = outerNodePos;
|
|
385
|
+
currentNodeRelPos = getRelativePos(view.state, currentNodePos);
|
|
386
|
+
onNodeChange == null ? void 0 : onNodeChange({ editor, node: currentNode, pos: currentNodePos });
|
|
387
|
+
repositionDragHandle(domNode);
|
|
388
|
+
},
|
|
389
|
+
// TODO: Kills even on hot reload
|
|
390
|
+
destroy() {
|
|
227
391
|
if (element) {
|
|
228
|
-
|
|
392
|
+
removeNode(wrapper);
|
|
229
393
|
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
},
|
|
397
|
+
props: {
|
|
398
|
+
handleDOMEvents: {
|
|
399
|
+
mouseleave(_view, e) {
|
|
400
|
+
if (locked) {
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
if (e.target && !wrapper.contains(e.relatedTarget)) {
|
|
404
|
+
hideHandle();
|
|
405
|
+
currentNode = null;
|
|
406
|
+
currentNodePos = -1;
|
|
407
|
+
onNodeChange == null ? void 0 : onNodeChange({ editor, node: null, pos: -1 });
|
|
408
|
+
}
|
|
409
|
+
return false;
|
|
410
|
+
},
|
|
411
|
+
mousemove(view, e) {
|
|
412
|
+
if (!element || locked) {
|
|
413
|
+
return false;
|
|
414
|
+
}
|
|
415
|
+
const nodeData = findElementNextToCoords({
|
|
416
|
+
x: e.clientX,
|
|
417
|
+
y: e.clientY,
|
|
418
|
+
direction: "right",
|
|
419
|
+
editor
|
|
420
|
+
});
|
|
421
|
+
if (!nodeData.resultElement) {
|
|
422
|
+
return false;
|
|
423
|
+
}
|
|
424
|
+
let domNode = nodeData.resultElement;
|
|
425
|
+
domNode = getOuterDomNode(view, domNode);
|
|
426
|
+
if (domNode === view.dom) {
|
|
427
|
+
return false;
|
|
428
|
+
}
|
|
429
|
+
if ((domNode == null ? void 0 : domNode.nodeType) !== 1) {
|
|
430
|
+
return false;
|
|
431
|
+
}
|
|
432
|
+
const domNodePos = view.posAtDOM(domNode, 0);
|
|
433
|
+
const outerNode = getOuterNode(editor.state.doc, domNodePos);
|
|
434
|
+
if (outerNode !== currentNode) {
|
|
435
|
+
const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos);
|
|
436
|
+
currentNode = outerNode;
|
|
437
|
+
currentNodePos = outerNodePos;
|
|
438
|
+
currentNodeRelPos = getRelativePos(view.state, currentNodePos);
|
|
439
|
+
onNodeChange == null ? void 0 : onNodeChange({ editor, node: currentNode, pos: currentNodePos });
|
|
440
|
+
repositionDragHandle(domNode);
|
|
441
|
+
showHandle();
|
|
442
|
+
}
|
|
443
|
+
return false;
|
|
444
|
+
}
|
|
235
445
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
state: {
|
|
240
|
-
init() {
|
|
241
|
-
return { locked: false };
|
|
242
|
-
},
|
|
243
|
-
apply(tr, value, oldState, state) {
|
|
244
|
-
const isLocked = tr.getMeta('lockDragHandle');
|
|
245
|
-
const hideDragHandle = tr.getMeta('hideDragHandle');
|
|
246
|
-
if (isLocked !== undefined) {
|
|
247
|
-
locked = isLocked;
|
|
248
|
-
}
|
|
249
|
-
if (hideDragHandle && popup) {
|
|
250
|
-
popup.hide();
|
|
251
|
-
locked = false;
|
|
252
|
-
currentNode = null;
|
|
253
|
-
currentNodePos = -1;
|
|
254
|
-
onNodeChange === null || onNodeChange === void 0 ? void 0 : onNodeChange({ editor, node: null, pos: -1 });
|
|
255
|
-
return value;
|
|
256
|
-
}
|
|
257
|
-
// Something has changed and drag handler is visible…
|
|
258
|
-
if (tr.docChanged && currentNodePos !== -1 && element && popup) {
|
|
259
|
-
// Yjs replaces the entire document on every incoming change and needs a special handling.
|
|
260
|
-
// If change comes from another user …
|
|
261
|
-
if (extensionCollaboration.isChangeOrigin(tr)) {
|
|
262
|
-
// https://discuss.yjs.dev/t/y-prosemirror-mapping-a-single-relative-position-when-doc-changes/851/3
|
|
263
|
-
const newPos = getAbsolutePos(state, currentNodeRelPos);
|
|
264
|
-
if (newPos !== currentNodePos) {
|
|
265
|
-
// Set the new position for our current node.
|
|
266
|
-
currentNodePos = newPos;
|
|
267
|
-
// We will get the outer node with data and position in views update method.
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
// … otherwise use ProseMirror mapping to update the position.
|
|
272
|
-
const newPos = tr.mapping.map(currentNodePos);
|
|
273
|
-
if (newPos !== currentNodePos) {
|
|
274
|
-
// TODO: Remove
|
|
275
|
-
// console.log('Position has changed …', { old: currentNodePos, new: newPos }, tr);
|
|
276
|
-
// Set the new position for our current node.
|
|
277
|
-
currentNodePos = newPos;
|
|
278
|
-
// Memorize relative position to retrieve absolute position in case of collaboration
|
|
279
|
-
currentNodeRelPos = getRelativePos(state, currentNodePos);
|
|
280
|
-
// We will get the outer node with data and position in views update method.
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return value;
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
view: view => {
|
|
288
|
-
var _a;
|
|
289
|
-
element.draggable = true;
|
|
290
|
-
element.style.pointerEvents = 'auto';
|
|
291
|
-
(_a = editor.view.dom.parentElement) === null || _a === void 0 ? void 0 : _a.appendChild(wrapper);
|
|
292
|
-
wrapper.appendChild(element);
|
|
293
|
-
wrapper.style.pointerEvents = 'none';
|
|
294
|
-
wrapper.style.position = 'absolute';
|
|
295
|
-
wrapper.style.top = '0';
|
|
296
|
-
wrapper.style.left = '0';
|
|
297
|
-
return {
|
|
298
|
-
update(_, oldState) {
|
|
299
|
-
if (!element) {
|
|
300
|
-
return;
|
|
301
|
-
}
|
|
302
|
-
if (!editor.isEditable) {
|
|
303
|
-
popup === null || popup === void 0 ? void 0 : popup.destroy();
|
|
304
|
-
popup = null;
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
if (!popup) {
|
|
308
|
-
popup = tippy__default.default(view.dom, {
|
|
309
|
-
getReferenceClientRect: null,
|
|
310
|
-
interactive: true,
|
|
311
|
-
trigger: 'manual',
|
|
312
|
-
placement: 'left-start',
|
|
313
|
-
hideOnClick: false,
|
|
314
|
-
duration: 100,
|
|
315
|
-
popperOptions: {
|
|
316
|
-
modifiers: [
|
|
317
|
-
{ name: 'flip', enabled: false },
|
|
318
|
-
{
|
|
319
|
-
name: 'preventOverflow',
|
|
320
|
-
options: {
|
|
321
|
-
rootBoundary: 'document',
|
|
322
|
-
mainAxis: false,
|
|
323
|
-
},
|
|
324
|
-
},
|
|
325
|
-
],
|
|
326
|
-
},
|
|
327
|
-
...tippyOptions,
|
|
328
|
-
appendTo: wrapper,
|
|
329
|
-
content: element,
|
|
330
|
-
});
|
|
331
|
-
}
|
|
332
|
-
// Prevent element being draggend while being open.
|
|
333
|
-
if (locked) {
|
|
334
|
-
element.draggable = false;
|
|
335
|
-
}
|
|
336
|
-
else {
|
|
337
|
-
element.draggable = true;
|
|
338
|
-
}
|
|
339
|
-
// Do not close on updates (e.g. changing padding of a section or collaboration events)
|
|
340
|
-
// popup?.hide();
|
|
341
|
-
// Recalculate popup position if doc has changend and drag handler is visible.
|
|
342
|
-
if (view.state.doc.eq(oldState.doc) || currentNodePos === -1) {
|
|
343
|
-
return;
|
|
344
|
-
}
|
|
345
|
-
// Get domNode from (new) position.
|
|
346
|
-
let domNode = view.nodeDOM(currentNodePos);
|
|
347
|
-
// Since old element could have been wrapped, we need to find
|
|
348
|
-
// the outer node and take its position and node data.
|
|
349
|
-
domNode = getOuterDomNode(view, domNode);
|
|
350
|
-
// Skip if domNode is editor dom.
|
|
351
|
-
if (domNode === view.dom) {
|
|
352
|
-
return;
|
|
353
|
-
}
|
|
354
|
-
// We only want `Element`.
|
|
355
|
-
if ((domNode === null || domNode === void 0 ? void 0 : domNode.nodeType) !== 1) {
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
const domNodePos = view.posAtDOM(domNode, 0);
|
|
359
|
-
const outerNode = getOuterNode(editor.state.doc, domNodePos);
|
|
360
|
-
const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos); // TODO: needed?
|
|
361
|
-
currentNode = outerNode;
|
|
362
|
-
currentNodePos = outerNodePos;
|
|
363
|
-
// Memorize relative position to retrieve absolute position in case of collaboration
|
|
364
|
-
currentNodeRelPos = getRelativePos(view.state, currentNodePos);
|
|
365
|
-
// TODO: Remove
|
|
366
|
-
// console.log('View has updated: callback with new data and repositioning of popup …', {
|
|
367
|
-
// domNode,
|
|
368
|
-
// currentNodePos,
|
|
369
|
-
// currentNode,
|
|
370
|
-
// rect: (domNode as Element).getBoundingClientRect(),
|
|
371
|
-
// });
|
|
372
|
-
onNodeChange === null || onNodeChange === void 0 ? void 0 : onNodeChange({ editor, node: currentNode, pos: currentNodePos });
|
|
373
|
-
// Update Tippys getReferenceClientRect since domNode might have changed.
|
|
374
|
-
popup.setProps({
|
|
375
|
-
getReferenceClientRect: () => domNode.getBoundingClientRect(),
|
|
376
|
-
});
|
|
377
|
-
},
|
|
378
|
-
// TODO: Kills even on hot reload
|
|
379
|
-
destroy() {
|
|
380
|
-
popup === null || popup === void 0 ? void 0 : popup.destroy();
|
|
381
|
-
if (element) {
|
|
382
|
-
removeNode(wrapper);
|
|
383
|
-
}
|
|
384
|
-
},
|
|
385
|
-
};
|
|
386
|
-
},
|
|
387
|
-
props: {
|
|
388
|
-
handleDOMEvents: {
|
|
389
|
-
mouseleave(_view, e) {
|
|
390
|
-
// Do not hide open popup on mouseleave.
|
|
391
|
-
if (locked) {
|
|
392
|
-
return false;
|
|
393
|
-
}
|
|
394
|
-
// If e.target is not inside the wrapper, hide.
|
|
395
|
-
if (e.target && !wrapper.contains(e.relatedTarget)) {
|
|
396
|
-
popup === null || popup === void 0 ? void 0 : popup.hide();
|
|
397
|
-
currentNode = null;
|
|
398
|
-
currentNodePos = -1;
|
|
399
|
-
onNodeChange === null || onNodeChange === void 0 ? void 0 : onNodeChange({ editor, node: null, pos: -1 });
|
|
400
|
-
}
|
|
401
|
-
return false;
|
|
402
|
-
},
|
|
403
|
-
mousemove(view, e) {
|
|
404
|
-
// Do not continue if popup is not initialized or open.
|
|
405
|
-
if (!element || !popup || locked) {
|
|
406
|
-
return false;
|
|
407
|
-
}
|
|
408
|
-
const nodeData = findElementNextToCoords({
|
|
409
|
-
x: e.clientX,
|
|
410
|
-
y: e.clientY,
|
|
411
|
-
direction: 'right',
|
|
412
|
-
editor,
|
|
413
|
-
});
|
|
414
|
-
// Skip if there is no node next to coords
|
|
415
|
-
if (!nodeData.resultElement) {
|
|
416
|
-
return false;
|
|
417
|
-
}
|
|
418
|
-
let domNode = nodeData.resultElement;
|
|
419
|
-
domNode = getOuterDomNode(view, domNode);
|
|
420
|
-
// Skip if domNode is editor dom.
|
|
421
|
-
if (domNode === view.dom) {
|
|
422
|
-
return false;
|
|
423
|
-
}
|
|
424
|
-
// We only want `Element`.
|
|
425
|
-
if ((domNode === null || domNode === void 0 ? void 0 : domNode.nodeType) !== 1) {
|
|
426
|
-
return false;
|
|
427
|
-
}
|
|
428
|
-
const domNodePos = view.posAtDOM(domNode, 0);
|
|
429
|
-
const outerNode = getOuterNode(editor.state.doc, domNodePos);
|
|
430
|
-
if (outerNode !== currentNode) {
|
|
431
|
-
const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos);
|
|
432
|
-
currentNode = outerNode;
|
|
433
|
-
currentNodePos = outerNodePos;
|
|
434
|
-
// Memorize relative position to retrieve absolute position in case of collaboration
|
|
435
|
-
currentNodeRelPos = getRelativePos(view.state, currentNodePos);
|
|
436
|
-
// TODO: Remove
|
|
437
|
-
// console.log('Mousemove with changed node / node data …', {
|
|
438
|
-
// domNode,
|
|
439
|
-
// currentNodePos,
|
|
440
|
-
// currentNode,
|
|
441
|
-
// rect: (domNode as Element).getBoundingClientRect(),
|
|
442
|
-
// });
|
|
443
|
-
onNodeChange === null || onNodeChange === void 0 ? void 0 : onNodeChange({ editor, node: currentNode, pos: currentNodePos });
|
|
444
|
-
// Set nodes clientRect.
|
|
445
|
-
popup.setProps({
|
|
446
|
-
getReferenceClientRect: () => domNode.getBoundingClientRect(),
|
|
447
|
-
});
|
|
448
|
-
popup.show();
|
|
449
|
-
}
|
|
450
|
-
return false;
|
|
451
|
-
},
|
|
452
|
-
},
|
|
453
|
-
},
|
|
454
|
-
});
|
|
446
|
+
}
|
|
447
|
+
})
|
|
448
|
+
};
|
|
455
449
|
};
|
|
456
450
|
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
451
|
+
// src/drag-handle.ts
|
|
452
|
+
var defaultComputePositionConfig = {
|
|
453
|
+
placement: "left-start",
|
|
454
|
+
strategy: "absolute"
|
|
455
|
+
};
|
|
456
|
+
var DragHandle = import_core.Extension.create({
|
|
457
|
+
name: "dragHandle",
|
|
458
|
+
addOptions() {
|
|
459
|
+
return {
|
|
460
|
+
render() {
|
|
461
|
+
const element = document.createElement("div");
|
|
462
|
+
element.classList.add("drag-handle");
|
|
463
|
+
return element;
|
|
464
|
+
},
|
|
465
|
+
computePositionConfig: {},
|
|
466
|
+
locked: false,
|
|
467
|
+
onNodeChange: () => {
|
|
468
|
+
return null;
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
},
|
|
472
|
+
addCommands() {
|
|
473
|
+
return {
|
|
474
|
+
lockDragHandle: () => ({ editor }) => {
|
|
475
|
+
this.options.locked = true;
|
|
476
|
+
return editor.commands.setMeta("lockDragHandle", this.options.locked);
|
|
477
|
+
},
|
|
478
|
+
unlockDragHandle: () => ({ editor }) => {
|
|
479
|
+
this.options.locked = false;
|
|
480
|
+
return editor.commands.setMeta("lockDragHandle", this.options.locked);
|
|
481
|
+
},
|
|
482
|
+
toggleDragHandle: () => ({ editor }) => {
|
|
483
|
+
this.options.locked = !this.options.locked;
|
|
484
|
+
return editor.commands.setMeta("lockDragHandle", this.options.locked);
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
},
|
|
488
|
+
addProseMirrorPlugins() {
|
|
489
|
+
const element = this.options.render();
|
|
490
|
+
return [
|
|
491
|
+
DragHandlePlugin({
|
|
492
|
+
computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },
|
|
493
|
+
element,
|
|
494
|
+
editor: this.editor,
|
|
495
|
+
onNodeChange: this.options.onNodeChange
|
|
496
|
+
}).plugin
|
|
497
|
+
];
|
|
498
|
+
}
|
|
498
499
|
});
|
|
499
500
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
exports
|
|
504
|
-
|
|
501
|
+
// src/index.ts
|
|
502
|
+
var index_default = DragHandle;
|
|
503
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
504
|
+
0 && (module.exports = {
|
|
505
|
+
DragHandle,
|
|
506
|
+
DragHandlePlugin,
|
|
507
|
+
defaultComputePositionConfig,
|
|
508
|
+
dragHandlePluginDefaultKey
|
|
509
|
+
});
|
|
510
|
+
//# sourceMappingURL=index.cjs.map
|