@tiptap/extension-drag-handle 3.16.0 → 3.17.0
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/dist/index.cjs +327 -71
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +252 -3
- package/dist/index.d.ts +252 -3
- package/dist/index.js +318 -64
- package/dist/index.js.map +1 -1
- package/package.json +9 -9
- package/src/drag-handle-plugin.ts +51 -18
- package/src/drag-handle.ts +56 -0
- package/src/helpers/defaultRules.ts +71 -0
- package/src/helpers/dragHandler.ts +56 -25
- package/src/helpers/edgeDetection.ts +109 -0
- package/src/helpers/findBestDragTarget.ts +140 -0
- package/src/helpers/findNextElementFromCursor.ts +62 -6
- package/src/helpers/normalizeOptions.ts +48 -0
- package/src/helpers/scoring.ts +56 -0
- package/src/index.ts +9 -0
- package/src/types/options.ts +117 -0
- package/src/types/rules.ts +84 -0
package/dist/index.cjs
CHANGED
|
@@ -24,21 +24,25 @@ __export(index_exports, {
|
|
|
24
24
|
DragHandlePlugin: () => DragHandlePlugin,
|
|
25
25
|
default: () => index_default,
|
|
26
26
|
defaultComputePositionConfig: () => defaultComputePositionConfig,
|
|
27
|
-
|
|
27
|
+
defaultRules: () => defaultRules,
|
|
28
|
+
dragHandlePluginDefaultKey: () => dragHandlePluginDefaultKey,
|
|
29
|
+
normalizeNestedOptions: () => normalizeNestedOptions
|
|
28
30
|
});
|
|
29
31
|
module.exports = __toCommonJS(index_exports);
|
|
30
32
|
|
|
31
33
|
// src/drag-handle.ts
|
|
32
|
-
var
|
|
34
|
+
var import_core2 = require("@tiptap/core");
|
|
33
35
|
|
|
34
36
|
// src/drag-handle-plugin.ts
|
|
35
37
|
var import_dom = require("@floating-ui/dom");
|
|
38
|
+
var import_core = require("@tiptap/core");
|
|
36
39
|
var import_extension_collaboration = require("@tiptap/extension-collaboration");
|
|
37
|
-
var
|
|
40
|
+
var import_state2 = require("@tiptap/pm/state");
|
|
38
41
|
var import_y_tiptap = require("@tiptap/y-tiptap");
|
|
39
42
|
|
|
40
43
|
// src/helpers/dragHandler.ts
|
|
41
44
|
var import_extension_node_range = require("@tiptap/extension-node-range");
|
|
45
|
+
var import_state = require("@tiptap/pm/state");
|
|
42
46
|
|
|
43
47
|
// src/helpers/cloneElement.ts
|
|
44
48
|
function getCSSText(element) {
|
|
@@ -59,6 +63,191 @@ function cloneElement(node) {
|
|
|
59
63
|
return clonedNode;
|
|
60
64
|
}
|
|
61
65
|
|
|
66
|
+
// src/helpers/defaultRules.ts
|
|
67
|
+
var listItemFirstChild = {
|
|
68
|
+
id: "listItemFirstChild",
|
|
69
|
+
evaluate: ({ parent, isFirst }) => {
|
|
70
|
+
if (!isFirst) {
|
|
71
|
+
return 0;
|
|
72
|
+
}
|
|
73
|
+
const listItemTypes = ["listItem", "taskItem"];
|
|
74
|
+
if (parent && listItemTypes.includes(parent.type.name)) {
|
|
75
|
+
return 1e3;
|
|
76
|
+
}
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var listWrapperDeprioritize = {
|
|
81
|
+
id: "listWrapperDeprioritize",
|
|
82
|
+
evaluate: ({ node }) => {
|
|
83
|
+
const listItemTypes = ["listItem", "taskItem"];
|
|
84
|
+
const firstChild = node.firstChild;
|
|
85
|
+
if (firstChild && listItemTypes.includes(firstChild.type.name)) {
|
|
86
|
+
return 1e3;
|
|
87
|
+
}
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var inlineContent = {
|
|
92
|
+
id: "inlineContent",
|
|
93
|
+
evaluate: ({ node }) => {
|
|
94
|
+
if (node.isInline || node.isText) {
|
|
95
|
+
return 1e3;
|
|
96
|
+
}
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
var defaultRules = [listItemFirstChild, listWrapperDeprioritize, inlineContent];
|
|
101
|
+
|
|
102
|
+
// src/helpers/edgeDetection.ts
|
|
103
|
+
var DEFAULT_EDGE_CONFIG = {
|
|
104
|
+
edges: ["left", "top"],
|
|
105
|
+
threshold: 12,
|
|
106
|
+
strength: 500
|
|
107
|
+
};
|
|
108
|
+
function normalizeEdgeDetection(input) {
|
|
109
|
+
if (input === void 0 || input === "left") {
|
|
110
|
+
return { ...DEFAULT_EDGE_CONFIG };
|
|
111
|
+
}
|
|
112
|
+
if (input === "right") {
|
|
113
|
+
return { edges: ["right", "top"], threshold: 12, strength: 500 };
|
|
114
|
+
}
|
|
115
|
+
if (input === "both") {
|
|
116
|
+
return { edges: ["left", "right", "top"], threshold: 12, strength: 500 };
|
|
117
|
+
}
|
|
118
|
+
if (input === "none") {
|
|
119
|
+
return { edges: [], threshold: 0, strength: 0 };
|
|
120
|
+
}
|
|
121
|
+
return { ...DEFAULT_EDGE_CONFIG, ...input };
|
|
122
|
+
}
|
|
123
|
+
function isNearEdge(coords, element, config) {
|
|
124
|
+
if (config.edges.length === 0) {
|
|
125
|
+
return false;
|
|
126
|
+
}
|
|
127
|
+
const rect = element.getBoundingClientRect();
|
|
128
|
+
const { threshold, edges } = config;
|
|
129
|
+
return edges.some((edge) => {
|
|
130
|
+
if (edge === "left") {
|
|
131
|
+
return coords.x - rect.left < threshold;
|
|
132
|
+
}
|
|
133
|
+
if (edge === "right") {
|
|
134
|
+
return rect.right - coords.x < threshold;
|
|
135
|
+
}
|
|
136
|
+
if (edge === "top") {
|
|
137
|
+
return coords.y - rect.top < threshold;
|
|
138
|
+
}
|
|
139
|
+
if (edge === "bottom") {
|
|
140
|
+
return rect.bottom - coords.y < threshold;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
function calculateEdgeDeduction(coords, element, config, depth) {
|
|
146
|
+
if (!element || config.edges.length === 0) {
|
|
147
|
+
return 0;
|
|
148
|
+
}
|
|
149
|
+
if (isNearEdge(coords, element, config)) {
|
|
150
|
+
return config.strength * depth;
|
|
151
|
+
}
|
|
152
|
+
return 0;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// src/helpers/scoring.ts
|
|
156
|
+
var BASE_SCORE = 1e3;
|
|
157
|
+
function calculateScore(context, rules, edgeConfig, coords) {
|
|
158
|
+
let score = BASE_SCORE;
|
|
159
|
+
let excluded = false;
|
|
160
|
+
rules.every((rule) => {
|
|
161
|
+
const deduction = rule.evaluate(context);
|
|
162
|
+
score -= deduction;
|
|
163
|
+
if (score <= 0) {
|
|
164
|
+
excluded = true;
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
return true;
|
|
168
|
+
});
|
|
169
|
+
if (excluded) {
|
|
170
|
+
return -1;
|
|
171
|
+
}
|
|
172
|
+
const dom = context.view.nodeDOM(context.pos);
|
|
173
|
+
score -= calculateEdgeDeduction(coords, dom, edgeConfig, context.depth);
|
|
174
|
+
if (score <= 0) {
|
|
175
|
+
return -1;
|
|
176
|
+
}
|
|
177
|
+
return score;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// src/helpers/findBestDragTarget.ts
|
|
181
|
+
function hasAncestorOfType($pos, depth, allowedTypes) {
|
|
182
|
+
const ancestorDepths = Array.from({ length: depth }, (_, i) => depth - 1 - i);
|
|
183
|
+
return ancestorDepths.some((d) => allowedTypes.includes($pos.node(d).type.name));
|
|
184
|
+
}
|
|
185
|
+
function findBestDragTarget(view, coords, options) {
|
|
186
|
+
if (!Number.isFinite(coords.x) || !Number.isFinite(coords.y)) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
const posInfo = view.posAtCoords({ left: coords.x, top: coords.y });
|
|
190
|
+
if (!posInfo) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
const { doc } = view.state;
|
|
194
|
+
const $pos = doc.resolve(posInfo.pos);
|
|
195
|
+
const rules = [];
|
|
196
|
+
if (options.defaultRules) {
|
|
197
|
+
rules.push(...defaultRules);
|
|
198
|
+
}
|
|
199
|
+
rules.push(...options.rules);
|
|
200
|
+
const depthLevels = Array.from({ length: $pos.depth }, (_, i) => $pos.depth - i);
|
|
201
|
+
const candidates = depthLevels.map((depth) => {
|
|
202
|
+
const node = $pos.node(depth);
|
|
203
|
+
const nodePos = $pos.before(depth);
|
|
204
|
+
if (options.allowedContainers && depth > 0) {
|
|
205
|
+
const inAllowedContainer = hasAncestorOfType($pos, depth, options.allowedContainers);
|
|
206
|
+
if (!inAllowedContainer) {
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
const parent = depth > 0 ? $pos.node(depth - 1) : null;
|
|
211
|
+
const index = depth > 0 ? $pos.index(depth - 1) : 0;
|
|
212
|
+
const siblingCount = parent ? parent.childCount : 1;
|
|
213
|
+
const context = {
|
|
214
|
+
node,
|
|
215
|
+
pos: nodePos,
|
|
216
|
+
depth,
|
|
217
|
+
parent,
|
|
218
|
+
index,
|
|
219
|
+
isFirst: index === 0,
|
|
220
|
+
isLast: index === siblingCount - 1,
|
|
221
|
+
$pos,
|
|
222
|
+
view
|
|
223
|
+
};
|
|
224
|
+
const score = calculateScore(context, rules, options.edgeDetection, coords);
|
|
225
|
+
if (score < 0) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
const dom = view.nodeDOM(nodePos);
|
|
229
|
+
return { node, pos: nodePos, depth, score, dom };
|
|
230
|
+
}).filter((candidate) => candidate !== null);
|
|
231
|
+
if (candidates.length === 0) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
candidates.sort((a, b) => {
|
|
235
|
+
if (b.score !== a.score) {
|
|
236
|
+
return b.score - a.score;
|
|
237
|
+
}
|
|
238
|
+
return b.depth - a.depth;
|
|
239
|
+
});
|
|
240
|
+
const winner = candidates[0];
|
|
241
|
+
if (!winner.dom) {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
return {
|
|
245
|
+
node: winner.node,
|
|
246
|
+
pos: winner.pos,
|
|
247
|
+
dom: winner.dom
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
62
251
|
// src/helpers/findNextElementFromCursor.ts
|
|
63
252
|
function findClosestTopLevelBlock(element, view) {
|
|
64
253
|
let current = element;
|
|
@@ -67,15 +256,24 @@ function findClosestTopLevelBlock(element, view) {
|
|
|
67
256
|
}
|
|
68
257
|
return (current == null ? void 0 : current.parentElement) === view.dom ? current : void 0;
|
|
69
258
|
}
|
|
259
|
+
function isValidRect(rect) {
|
|
260
|
+
return Number.isFinite(rect.top) && Number.isFinite(rect.bottom) && Number.isFinite(rect.left) && Number.isFinite(rect.right) && rect.width > 0 && rect.height > 0;
|
|
261
|
+
}
|
|
70
262
|
function clampToContent(view, x, y, inset = 5) {
|
|
263
|
+
if (!Number.isFinite(x) || !Number.isFinite(y)) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
71
266
|
const container = view.dom;
|
|
72
267
|
const firstBlock = container.firstElementChild;
|
|
73
268
|
const lastBlock = container.lastElementChild;
|
|
74
269
|
if (!firstBlock || !lastBlock) {
|
|
75
|
-
return
|
|
270
|
+
return null;
|
|
76
271
|
}
|
|
77
272
|
const topRect = firstBlock.getBoundingClientRect();
|
|
78
273
|
const botRect = lastBlock.getBoundingClientRect();
|
|
274
|
+
if (!isValidRect(topRect) || !isValidRect(botRect)) {
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
79
277
|
const clampedY = Math.min(Math.max(topRect.top + inset, y), botRect.bottom - inset);
|
|
80
278
|
const epsilon = 0.5;
|
|
81
279
|
const sameLeft = Math.abs(topRect.left - botRect.left) < epsilon;
|
|
@@ -86,12 +284,30 @@ function clampToContent(view, x, y, inset = 5) {
|
|
|
86
284
|
} else {
|
|
87
285
|
}
|
|
88
286
|
const clampedX = Math.min(Math.max(rowRect.left + inset, x), rowRect.right - inset);
|
|
287
|
+
if (!Number.isFinite(clampedX) || !Number.isFinite(clampedY)) {
|
|
288
|
+
return null;
|
|
289
|
+
}
|
|
89
290
|
return { x: clampedX, y: clampedY };
|
|
90
291
|
}
|
|
91
292
|
var findElementNextToCoords = (options) => {
|
|
92
|
-
const { x, y, editor } = options;
|
|
293
|
+
const { x, y, editor, nestedOptions } = options;
|
|
93
294
|
const { view, state } = editor;
|
|
94
|
-
const
|
|
295
|
+
const clamped = clampToContent(view, x, y, 5);
|
|
296
|
+
if (!clamped) {
|
|
297
|
+
return { resultElement: null, resultNode: null, pos: null };
|
|
298
|
+
}
|
|
299
|
+
const { x: clampedX, y: clampedY } = clamped;
|
|
300
|
+
if (nestedOptions == null ? void 0 : nestedOptions.enabled) {
|
|
301
|
+
const target = findBestDragTarget(view, { x: clampedX, y: clampedY }, nestedOptions);
|
|
302
|
+
if (!target) {
|
|
303
|
+
return { resultElement: null, resultNode: null, pos: null };
|
|
304
|
+
}
|
|
305
|
+
return {
|
|
306
|
+
resultElement: target.dom,
|
|
307
|
+
resultNode: target.node,
|
|
308
|
+
pos: target.pos
|
|
309
|
+
};
|
|
310
|
+
}
|
|
95
311
|
const elements = view.root.elementsFromPoint(clampedX, clampedY);
|
|
96
312
|
let block;
|
|
97
313
|
Array.prototype.some.call(elements, (el) => {
|
|
@@ -131,31 +347,6 @@ var findElementNextToCoords = (options) => {
|
|
|
131
347
|
};
|
|
132
348
|
};
|
|
133
349
|
|
|
134
|
-
// src/helpers/getComputedStyle.ts
|
|
135
|
-
function getComputedStyle2(node, property) {
|
|
136
|
-
const style = window.getComputedStyle(node);
|
|
137
|
-
return style[property];
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
// src/helpers/minMax.ts
|
|
141
|
-
function minMax(value = 0, min = 0, max = 0) {
|
|
142
|
-
return Math.min(Math.max(value, min), max);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
// src/helpers/getInnerCoords.ts
|
|
146
|
-
function getInnerCoords(view, x, y) {
|
|
147
|
-
const paddingLeft = parseInt(getComputedStyle2(view.dom, "paddingLeft"), 10);
|
|
148
|
-
const paddingRight = parseInt(getComputedStyle2(view.dom, "paddingRight"), 10);
|
|
149
|
-
const borderLeft = parseInt(getComputedStyle2(view.dom, "borderLeftWidth"), 10);
|
|
150
|
-
const borderRight = parseInt(getComputedStyle2(view.dom, "borderLeftWidth"), 10);
|
|
151
|
-
const bounds = view.dom.getBoundingClientRect();
|
|
152
|
-
const coords = {
|
|
153
|
-
left: minMax(x, bounds.left + paddingLeft + borderLeft, bounds.right - paddingRight - borderRight),
|
|
154
|
-
top: y
|
|
155
|
-
};
|
|
156
|
-
return coords;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
350
|
// src/helpers/removeNode.ts
|
|
160
351
|
function removeNode(node) {
|
|
161
352
|
var _a;
|
|
@@ -163,39 +354,39 @@ function removeNode(node) {
|
|
|
163
354
|
}
|
|
164
355
|
|
|
165
356
|
// src/helpers/dragHandler.ts
|
|
166
|
-
function getDragHandleRanges(event, editor) {
|
|
357
|
+
function getDragHandleRanges(event, editor, nestedOptions, dragContext) {
|
|
167
358
|
const { doc } = editor.view.state;
|
|
359
|
+
if ((nestedOptions == null ? void 0 : nestedOptions.enabled) && (dragContext == null ? void 0 : dragContext.node) && dragContext.pos >= 0) {
|
|
360
|
+
const nodeStart = dragContext.pos;
|
|
361
|
+
const nodeEnd = dragContext.pos + dragContext.node.nodeSize;
|
|
362
|
+
return [
|
|
363
|
+
{
|
|
364
|
+
$from: doc.resolve(nodeStart),
|
|
365
|
+
$to: doc.resolve(nodeEnd)
|
|
366
|
+
}
|
|
367
|
+
];
|
|
368
|
+
}
|
|
168
369
|
const result = findElementNextToCoords({
|
|
169
370
|
editor,
|
|
170
371
|
x: event.clientX,
|
|
171
372
|
y: event.clientY,
|
|
172
|
-
direction: "right"
|
|
373
|
+
direction: "right",
|
|
374
|
+
nestedOptions
|
|
173
375
|
});
|
|
174
376
|
if (!result.resultNode || result.pos === null) {
|
|
175
377
|
return [];
|
|
176
378
|
}
|
|
177
|
-
const x = event.clientX;
|
|
178
|
-
const coords = getInnerCoords(editor.view, x, event.clientY);
|
|
179
|
-
const posAtCoords = editor.view.posAtCoords(coords);
|
|
180
|
-
if (!posAtCoords) {
|
|
181
|
-
return [];
|
|
182
|
-
}
|
|
183
|
-
const { pos } = posAtCoords;
|
|
184
|
-
const nodeAt = doc.resolve(pos).parent;
|
|
185
|
-
if (!nodeAt) {
|
|
186
|
-
return [];
|
|
187
|
-
}
|
|
188
379
|
const $from = doc.resolve(result.pos);
|
|
189
|
-
const $to = doc.resolve(result.pos +
|
|
380
|
+
const $to = doc.resolve(result.pos + result.resultNode.nodeSize);
|
|
190
381
|
return (0, import_extension_node_range.getSelectionRanges)($from, $to, 0);
|
|
191
382
|
}
|
|
192
|
-
function dragHandler(event, editor) {
|
|
383
|
+
function dragHandler(event, editor, nestedOptions, dragContext) {
|
|
193
384
|
const { view } = editor;
|
|
194
385
|
if (!event.dataTransfer) {
|
|
195
386
|
return;
|
|
196
387
|
}
|
|
197
388
|
const { empty, $from, $to } = view.state.selection;
|
|
198
|
-
const dragHandleRanges = getDragHandleRanges(event, editor);
|
|
389
|
+
const dragHandleRanges = getDragHandleRanges(event, editor, nestedOptions, dragContext);
|
|
199
390
|
const selectionRanges = (0, import_extension_node_range.getSelectionRanges)($from, $to, 0);
|
|
200
391
|
const isDragHandleWithinSelection = selectionRanges.some((range) => {
|
|
201
392
|
return dragHandleRanges.find((dragHandleRange) => {
|
|
@@ -210,8 +401,16 @@ function dragHandler(event, editor) {
|
|
|
210
401
|
const wrapper = document.createElement("div");
|
|
211
402
|
const from = ranges[0].$from.pos;
|
|
212
403
|
const to = ranges[ranges.length - 1].$to.pos;
|
|
213
|
-
const
|
|
214
|
-
|
|
404
|
+
const isNestedDrag = (nestedOptions == null ? void 0 : nestedOptions.enabled) && (dragContext == null ? void 0 : dragContext.node);
|
|
405
|
+
let slice;
|
|
406
|
+
let selection;
|
|
407
|
+
if (isNestedDrag) {
|
|
408
|
+
slice = view.state.doc.slice(from, to);
|
|
409
|
+
selection = import_state.NodeSelection.create(view.state.doc, from);
|
|
410
|
+
} else {
|
|
411
|
+
selection = import_extension_node_range.NodeRangeSelection.create(view.state.doc, from, to);
|
|
412
|
+
slice = selection.content();
|
|
413
|
+
}
|
|
215
414
|
ranges.forEach((range) => {
|
|
216
415
|
const element = view.nodeDOM(range.$from.pos);
|
|
217
416
|
const clonedElement = cloneElement(element);
|
|
@@ -278,7 +477,7 @@ var getOuterDomNode = (view, domNode) => {
|
|
|
278
477
|
}
|
|
279
478
|
return tmpDomNode;
|
|
280
479
|
};
|
|
281
|
-
var dragHandlePluginDefaultKey = new
|
|
480
|
+
var dragHandlePluginDefaultKey = new import_state2.PluginKey("dragHandle");
|
|
282
481
|
var DragHandlePlugin = ({
|
|
283
482
|
pluginKey = dragHandlePluginDefaultKey,
|
|
284
483
|
element,
|
|
@@ -287,7 +486,8 @@ var DragHandlePlugin = ({
|
|
|
287
486
|
getReferencedVirtualElement,
|
|
288
487
|
onNodeChange,
|
|
289
488
|
onElementDragStart,
|
|
290
|
-
onElementDragEnd
|
|
489
|
+
onElementDragEnd,
|
|
490
|
+
nestedOptions
|
|
291
491
|
}) => {
|
|
292
492
|
const wrapper = document.createElement("div");
|
|
293
493
|
let locked = false;
|
|
@@ -328,7 +528,7 @@ var DragHandlePlugin = ({
|
|
|
328
528
|
}
|
|
329
529
|
function onDragStart(e) {
|
|
330
530
|
onElementDragStart == null ? void 0 : onElementDragStart(e);
|
|
331
|
-
dragHandler(e, editor);
|
|
531
|
+
dragHandler(e, editor, nestedOptions, { node: currentNode, pos: currentNodePos });
|
|
332
532
|
if (element) {
|
|
333
533
|
element.dataset.dragging = "true";
|
|
334
534
|
}
|
|
@@ -346,21 +546,34 @@ var DragHandlePlugin = ({
|
|
|
346
546
|
element.dataset.dragging = "false";
|
|
347
547
|
}
|
|
348
548
|
}
|
|
549
|
+
function onDrop() {
|
|
550
|
+
if ((0, import_core.isFirefox)()) {
|
|
551
|
+
const editorElement = editor.view.dom;
|
|
552
|
+
requestAnimationFrame(() => {
|
|
553
|
+
if (editorElement.isContentEditable) {
|
|
554
|
+
editorElement.contentEditable = "false";
|
|
555
|
+
editorElement.contentEditable = "true";
|
|
556
|
+
}
|
|
557
|
+
});
|
|
558
|
+
}
|
|
559
|
+
}
|
|
349
560
|
element.addEventListener("dragstart", onDragStart);
|
|
350
561
|
element.addEventListener("dragend", onDragEnd);
|
|
562
|
+
document.addEventListener("drop", onDrop);
|
|
351
563
|
wrapper.appendChild(element);
|
|
352
564
|
return {
|
|
353
565
|
unbind() {
|
|
354
566
|
element.removeEventListener("dragstart", onDragStart);
|
|
355
567
|
element.removeEventListener("dragend", onDragEnd);
|
|
568
|
+
document.removeEventListener("drop", onDrop);
|
|
356
569
|
if (rafId) {
|
|
357
570
|
cancelAnimationFrame(rafId);
|
|
358
571
|
rafId = null;
|
|
359
572
|
pendingMouseCoords = null;
|
|
360
573
|
}
|
|
361
574
|
},
|
|
362
|
-
plugin: new
|
|
363
|
-
key: typeof pluginKey === "string" ? new
|
|
575
|
+
plugin: new import_state2.Plugin({
|
|
576
|
+
key: typeof pluginKey === "string" ? new import_state2.PluginKey(pluginKey) : pluginKey,
|
|
364
577
|
state: {
|
|
365
578
|
init() {
|
|
366
579
|
return { locked: false };
|
|
@@ -442,6 +655,9 @@ var DragHandlePlugin = ({
|
|
|
442
655
|
},
|
|
443
656
|
// TODO: Kills even on hot reload
|
|
444
657
|
destroy() {
|
|
658
|
+
element.removeEventListener("dragstart", onDragStart);
|
|
659
|
+
element.removeEventListener("dragend", onDragEnd);
|
|
660
|
+
document.removeEventListener("drop", onDrop);
|
|
445
661
|
if (rafId) {
|
|
446
662
|
cancelAnimationFrame(rafId);
|
|
447
663
|
rafId = null;
|
|
@@ -499,25 +715,30 @@ var DragHandlePlugin = ({
|
|
|
499
715
|
x,
|
|
500
716
|
y,
|
|
501
717
|
direction: "right",
|
|
502
|
-
editor
|
|
718
|
+
editor,
|
|
719
|
+
nestedOptions
|
|
503
720
|
});
|
|
504
721
|
if (!nodeData.resultElement) {
|
|
505
722
|
return;
|
|
506
723
|
}
|
|
507
724
|
let domNode = nodeData.resultElement;
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
725
|
+
let targetNode = nodeData.resultNode;
|
|
726
|
+
let targetPos = nodeData.pos;
|
|
727
|
+
if (!(nestedOptions == null ? void 0 : nestedOptions.enabled)) {
|
|
728
|
+
domNode = getOuterDomNode(view, domNode);
|
|
729
|
+
if (domNode === view.dom) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
if ((domNode == null ? void 0 : domNode.nodeType) !== 1) {
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const domNodePos = view.posAtDOM(domNode, 0);
|
|
736
|
+
targetNode = getOuterNode(editor.state.doc, domNodePos);
|
|
737
|
+
targetPos = getOuterNodePos(editor.state.doc, domNodePos);
|
|
514
738
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos);
|
|
519
|
-
currentNode = outerNode;
|
|
520
|
-
currentNodePos = outerNodePos;
|
|
739
|
+
if (targetNode !== currentNode) {
|
|
740
|
+
currentNode = targetNode;
|
|
741
|
+
currentNodePos = targetPos != null ? targetPos : -1;
|
|
521
742
|
currentNodeRelPos = getRelativePos(view.state, currentNodePos);
|
|
522
743
|
onNodeChange == null ? void 0 : onNodeChange({ editor, node: currentNode, pos: currentNodePos });
|
|
523
744
|
repositionDragHandle(domNode);
|
|
@@ -532,12 +753,42 @@ var DragHandlePlugin = ({
|
|
|
532
753
|
};
|
|
533
754
|
};
|
|
534
755
|
|
|
756
|
+
// src/helpers/normalizeOptions.ts
|
|
757
|
+
function normalizeNestedOptions(input) {
|
|
758
|
+
var _a, _b;
|
|
759
|
+
if (input === false || input === void 0) {
|
|
760
|
+
return {
|
|
761
|
+
enabled: false,
|
|
762
|
+
rules: [],
|
|
763
|
+
defaultRules: true,
|
|
764
|
+
allowedContainers: void 0,
|
|
765
|
+
edgeDetection: normalizeEdgeDetection("none")
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
if (input === true) {
|
|
769
|
+
return {
|
|
770
|
+
enabled: true,
|
|
771
|
+
rules: [],
|
|
772
|
+
defaultRules: true,
|
|
773
|
+
allowedContainers: void 0,
|
|
774
|
+
edgeDetection: normalizeEdgeDetection("left")
|
|
775
|
+
};
|
|
776
|
+
}
|
|
777
|
+
return {
|
|
778
|
+
enabled: true,
|
|
779
|
+
rules: (_a = input.rules) != null ? _a : [],
|
|
780
|
+
defaultRules: (_b = input.defaultRules) != null ? _b : true,
|
|
781
|
+
allowedContainers: input.allowedContainers,
|
|
782
|
+
edgeDetection: normalizeEdgeDetection(input.edgeDetection)
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
|
|
535
786
|
// src/drag-handle.ts
|
|
536
787
|
var defaultComputePositionConfig = {
|
|
537
788
|
placement: "left-start",
|
|
538
789
|
strategy: "absolute"
|
|
539
790
|
};
|
|
540
|
-
var DragHandle =
|
|
791
|
+
var DragHandle = import_core2.Extension.create({
|
|
541
792
|
name: "dragHandle",
|
|
542
793
|
addOptions() {
|
|
543
794
|
return {
|
|
@@ -552,7 +803,8 @@ var DragHandle = import_core.Extension.create({
|
|
|
552
803
|
return null;
|
|
553
804
|
},
|
|
554
805
|
onElementDragStart: void 0,
|
|
555
|
-
onElementDragEnd: void 0
|
|
806
|
+
onElementDragEnd: void 0,
|
|
807
|
+
nested: false
|
|
556
808
|
};
|
|
557
809
|
},
|
|
558
810
|
addCommands() {
|
|
@@ -573,6 +825,7 @@ var DragHandle = import_core.Extension.create({
|
|
|
573
825
|
},
|
|
574
826
|
addProseMirrorPlugins() {
|
|
575
827
|
const element = this.options.render();
|
|
828
|
+
const nestedOptions = normalizeNestedOptions(this.options.nested);
|
|
576
829
|
return [
|
|
577
830
|
DragHandlePlugin({
|
|
578
831
|
computePositionConfig: { ...defaultComputePositionConfig, ...this.options.computePositionConfig },
|
|
@@ -581,7 +834,8 @@ var DragHandle = import_core.Extension.create({
|
|
|
581
834
|
editor: this.editor,
|
|
582
835
|
onNodeChange: this.options.onNodeChange,
|
|
583
836
|
onElementDragStart: this.options.onElementDragStart,
|
|
584
|
-
onElementDragEnd: this.options.onElementDragEnd
|
|
837
|
+
onElementDragEnd: this.options.onElementDragEnd,
|
|
838
|
+
nestedOptions
|
|
585
839
|
}).plugin
|
|
586
840
|
];
|
|
587
841
|
}
|
|
@@ -594,6 +848,8 @@ var index_default = DragHandle;
|
|
|
594
848
|
DragHandle,
|
|
595
849
|
DragHandlePlugin,
|
|
596
850
|
defaultComputePositionConfig,
|
|
597
|
-
|
|
851
|
+
defaultRules,
|
|
852
|
+
dragHandlePluginDefaultKey,
|
|
853
|
+
normalizeNestedOptions
|
|
598
854
|
});
|
|
599
855
|
//# sourceMappingURL=index.cjs.map
|