@tiptap/extension-drag-handle 3.27.1 → 3.27.3
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 +112 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +112 -66
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
- package/src/drag-handle-plugin.ts +59 -39
- package/src/helpers/findNextElementFromCursor.ts +57 -13
- package/src/helpers/nodeRangeDrop.ts +47 -0
package/dist/index.cjs
CHANGED
|
@@ -306,28 +306,41 @@ function findBestDragTarget(view, coords, options) {
|
|
|
306
306
|
|
|
307
307
|
// src/helpers/findNextElementFromCursor.ts
|
|
308
308
|
function findClosestTopLevelBlock(element, view) {
|
|
309
|
+
var _a;
|
|
309
310
|
let current = element;
|
|
310
311
|
while ((current == null ? void 0 : current.parentElement) && current.parentElement !== view.dom) {
|
|
311
312
|
current = current.parentElement;
|
|
312
313
|
}
|
|
313
|
-
|
|
314
|
+
if ((current == null ? void 0 : current.parentElement) !== view.dom) {
|
|
315
|
+
return void 0;
|
|
316
|
+
}
|
|
317
|
+
if (!((_a = current.pmViewDesc) == null ? void 0 : _a.node)) {
|
|
318
|
+
return void 0;
|
|
319
|
+
}
|
|
320
|
+
return current;
|
|
314
321
|
}
|
|
315
322
|
function isValidRect(rect) {
|
|
316
323
|
return Number.isFinite(rect.top) && Number.isFinite(rect.bottom) && Number.isFinite(rect.left) && Number.isFinite(rect.right) && rect.width > 0 && rect.height > 0;
|
|
317
324
|
}
|
|
325
|
+
function edgeBlockRect(container, edge) {
|
|
326
|
+
let current = edge === "first" ? container.firstElementChild : container.lastElementChild;
|
|
327
|
+
while (current) {
|
|
328
|
+
const rect = current.getBoundingClientRect();
|
|
329
|
+
if (isValidRect(rect)) {
|
|
330
|
+
return rect;
|
|
331
|
+
}
|
|
332
|
+
current = edge === "first" ? current.nextElementSibling : current.previousElementSibling;
|
|
333
|
+
}
|
|
334
|
+
return null;
|
|
335
|
+
}
|
|
318
336
|
function clampToContent(view, x, y, inset = 5) {
|
|
319
337
|
if (!Number.isFinite(x) || !Number.isFinite(y)) {
|
|
320
338
|
return null;
|
|
321
339
|
}
|
|
322
340
|
const container = view.dom;
|
|
323
|
-
const
|
|
324
|
-
const
|
|
325
|
-
if (!
|
|
326
|
-
return null;
|
|
327
|
-
}
|
|
328
|
-
const topRect = firstBlock.getBoundingClientRect();
|
|
329
|
-
const botRect = lastBlock.getBoundingClientRect();
|
|
330
|
-
if (!isValidRect(topRect) || !isValidRect(botRect)) {
|
|
341
|
+
const topRect = edgeBlockRect(container, "first");
|
|
342
|
+
const botRect = edgeBlockRect(container, "last");
|
|
343
|
+
if (!topRect || !botRect) {
|
|
331
344
|
return null;
|
|
332
345
|
}
|
|
333
346
|
const clampedY = Math.min(Math.max(topRect.top + inset, y), botRect.bottom - inset);
|
|
@@ -560,8 +573,56 @@ function dragHandler(event, editor, nestedOptions, dragContext, dragImagePropert
|
|
|
560
573
|
document.addEventListener("dragend", cleanupDragPreview);
|
|
561
574
|
}
|
|
562
575
|
|
|
576
|
+
// src/helpers/getOuterNode.ts
|
|
577
|
+
var getOuterNodePos = (doc, pos) => {
|
|
578
|
+
const resolvedPos = doc.resolve(pos);
|
|
579
|
+
const { depth } = resolvedPos;
|
|
580
|
+
if (depth === 0) {
|
|
581
|
+
return pos;
|
|
582
|
+
}
|
|
583
|
+
const a = resolvedPos.pos - resolvedPos.parentOffset;
|
|
584
|
+
return a - 1;
|
|
585
|
+
};
|
|
586
|
+
var getOuterNode = (doc, pos) => {
|
|
587
|
+
const node = doc.nodeAt(pos);
|
|
588
|
+
const resolvedPos = doc.resolve(pos);
|
|
589
|
+
let { depth } = resolvedPos;
|
|
590
|
+
let parent = node;
|
|
591
|
+
while (depth > 0) {
|
|
592
|
+
const currentNode = resolvedPos.node(depth);
|
|
593
|
+
depth -= 1;
|
|
594
|
+
if (depth === 0) {
|
|
595
|
+
parent = currentNode;
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
return parent;
|
|
599
|
+
};
|
|
600
|
+
|
|
563
601
|
// src/helpers/nodeRangeDrop.ts
|
|
564
602
|
var import_extension_node_range2 = require("@tiptap/extension-node-range");
|
|
603
|
+
function mapPendingRestoreAnchor(pendingRestore, tr, options) {
|
|
604
|
+
if (!tr.docChanged) {
|
|
605
|
+
return pendingRestore;
|
|
606
|
+
}
|
|
607
|
+
if (options.isChangeOrigin && pendingRestore.relativeAnchorPos != null) {
|
|
608
|
+
const newPos = options.getAbsolutePos(pendingRestore.relativeAnchorPos);
|
|
609
|
+
if (!Number.isFinite(newPos) || newPos <= 0) {
|
|
610
|
+
return null;
|
|
611
|
+
}
|
|
612
|
+
return {
|
|
613
|
+
...pendingRestore,
|
|
614
|
+
anchorPos: newPos
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1);
|
|
618
|
+
if (mappedResult.deleted) {
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
return {
|
|
622
|
+
...pendingRestore,
|
|
623
|
+
anchorPos: mappedResult.pos
|
|
624
|
+
};
|
|
625
|
+
}
|
|
565
626
|
function sumNodeSizes(parent, from, to) {
|
|
566
627
|
let size = 0;
|
|
567
628
|
for (let i = from; i < to; i += 1) {
|
|
@@ -608,31 +669,6 @@ function createDroppedNodeRangeSelection(doc, anchorPos, nodeCount, depth) {
|
|
|
608
669
|
}
|
|
609
670
|
}
|
|
610
671
|
|
|
611
|
-
// src/helpers/getOuterNode.ts
|
|
612
|
-
var getOuterNodePos = (doc, pos) => {
|
|
613
|
-
const resolvedPos = doc.resolve(pos);
|
|
614
|
-
const { depth } = resolvedPos;
|
|
615
|
-
if (depth === 0) {
|
|
616
|
-
return pos;
|
|
617
|
-
}
|
|
618
|
-
const a = resolvedPos.pos - resolvedPos.parentOffset;
|
|
619
|
-
return a - 1;
|
|
620
|
-
};
|
|
621
|
-
var getOuterNode = (doc, pos) => {
|
|
622
|
-
const node = doc.nodeAt(pos);
|
|
623
|
-
const resolvedPos = doc.resolve(pos);
|
|
624
|
-
let { depth } = resolvedPos;
|
|
625
|
-
let parent = node;
|
|
626
|
-
while (depth > 0) {
|
|
627
|
-
const currentNode = resolvedPos.node(depth);
|
|
628
|
-
depth -= 1;
|
|
629
|
-
if (depth === 0) {
|
|
630
|
-
parent = currentNode;
|
|
631
|
-
}
|
|
632
|
-
}
|
|
633
|
-
return parent;
|
|
634
|
-
};
|
|
635
|
-
|
|
636
672
|
// src/drag-handle-plugin.ts
|
|
637
673
|
var getRelativePos = (state, absolutePos) => {
|
|
638
674
|
const ystate = import_y_tiptap.ySyncPluginKey.getState(state);
|
|
@@ -682,10 +718,40 @@ var DragHandlePlugin = ({
|
|
|
682
718
|
let currentNodePos = -1;
|
|
683
719
|
let currentNodeRelPos;
|
|
684
720
|
let rafId = null;
|
|
685
|
-
let restoreRafId = null;
|
|
686
721
|
let pendingMouseCoords = null;
|
|
687
722
|
let activeDragRange = null;
|
|
688
723
|
let pendingRestore = null;
|
|
724
|
+
function clearDragRangeState() {
|
|
725
|
+
activeDragRange = null;
|
|
726
|
+
pendingRestore = null;
|
|
727
|
+
}
|
|
728
|
+
function remapPendingRestore(tr, state) {
|
|
729
|
+
if (!pendingRestore) {
|
|
730
|
+
return;
|
|
731
|
+
}
|
|
732
|
+
pendingRestore = mapPendingRestoreAnchor(pendingRestore, tr, {
|
|
733
|
+
isChangeOrigin: (0, import_extension_collaboration.isChangeOrigin)(tr),
|
|
734
|
+
getAbsolutePos: (relativePos) => getAbsolutePos(state, relativePos)
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
function buildRestoreTransaction(state) {
|
|
738
|
+
if (!pendingRestore) {
|
|
739
|
+
return null;
|
|
740
|
+
}
|
|
741
|
+
const nodeRangeSelection = createDroppedNodeRangeSelection(
|
|
742
|
+
state.doc,
|
|
743
|
+
pendingRestore.anchorPos,
|
|
744
|
+
pendingRestore.nodeCount,
|
|
745
|
+
pendingRestore.depth
|
|
746
|
+
);
|
|
747
|
+
if (!nodeRangeSelection) {
|
|
748
|
+
pendingRestore = null;
|
|
749
|
+
activeDragRange = null;
|
|
750
|
+
return null;
|
|
751
|
+
}
|
|
752
|
+
clearDragRangeState();
|
|
753
|
+
return state.tr.setSelection(nodeRangeSelection);
|
|
754
|
+
}
|
|
689
755
|
function hideHandle() {
|
|
690
756
|
if (!element) {
|
|
691
757
|
return;
|
|
@@ -744,17 +810,6 @@ var DragHandlePlugin = ({
|
|
|
744
810
|
element.dataset.dragging = "false";
|
|
745
811
|
}
|
|
746
812
|
}
|
|
747
|
-
function restoreNodeRangeSelection({ nodeCount, depth, anchorPos }) {
|
|
748
|
-
const nodeRangeSelection = createDroppedNodeRangeSelection(
|
|
749
|
-
editor.state.doc,
|
|
750
|
-
anchorPos,
|
|
751
|
-
nodeCount,
|
|
752
|
-
depth
|
|
753
|
-
);
|
|
754
|
-
if (nodeRangeSelection) {
|
|
755
|
-
editor.view.dispatch(editor.state.tr.setSelection(nodeRangeSelection));
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
813
|
function onDrop(e) {
|
|
759
814
|
if (!e.target || !editor.view.dom.contains(e.target)) {
|
|
760
815
|
return;
|
|
@@ -771,17 +826,14 @@ var DragHandlePlugin = ({
|
|
|
771
826
|
if (!activeDragRange || editor.view.state.selection.empty) {
|
|
772
827
|
return;
|
|
773
828
|
}
|
|
829
|
+
const anchorPos = editor.state.selection.from;
|
|
830
|
+
const relativeAnchorPos = getRelativePos(editor.state, anchorPos);
|
|
774
831
|
pendingRestore = {
|
|
775
832
|
...activeDragRange,
|
|
776
|
-
anchorPos
|
|
833
|
+
anchorPos,
|
|
834
|
+
relativeAnchorPos: relativeAnchorPos != null ? relativeAnchorPos : void 0
|
|
777
835
|
};
|
|
778
|
-
|
|
779
|
-
restoreRafId = null;
|
|
780
|
-
if (pendingRestore) {
|
|
781
|
-
restoreNodeRangeSelection(pendingRestore);
|
|
782
|
-
pendingRestore = null;
|
|
783
|
-
}
|
|
784
|
-
});
|
|
836
|
+
editor.view.dispatch(editor.state.tr.setMeta("addToHistory", false));
|
|
785
837
|
}
|
|
786
838
|
function cleanup() {
|
|
787
839
|
element.removeEventListener("dragstart", onDragStart);
|
|
@@ -792,10 +844,7 @@ var DragHandlePlugin = ({
|
|
|
792
844
|
rafId = null;
|
|
793
845
|
pendingMouseCoords = null;
|
|
794
846
|
}
|
|
795
|
-
|
|
796
|
-
cancelAnimationFrame(restoreRafId);
|
|
797
|
-
restoreRafId = null;
|
|
798
|
-
}
|
|
847
|
+
clearDragRangeState();
|
|
799
848
|
}
|
|
800
849
|
wrapper.appendChild(element);
|
|
801
850
|
return {
|
|
@@ -809,14 +858,7 @@ var DragHandlePlugin = ({
|
|
|
809
858
|
return { locked: false };
|
|
810
859
|
},
|
|
811
860
|
apply(tr, value, _oldState, state) {
|
|
812
|
-
|
|
813
|
-
const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1);
|
|
814
|
-
if (mappedResult.deleted) {
|
|
815
|
-
pendingRestore = null;
|
|
816
|
-
} else {
|
|
817
|
-
pendingRestore.anchorPos = mappedResult.pos;
|
|
818
|
-
}
|
|
819
|
-
}
|
|
861
|
+
remapPendingRestore(tr, state);
|
|
820
862
|
const isLocked = tr.getMeta("lockDragHandle");
|
|
821
863
|
const hideDragHandle = tr.getMeta("hideDragHandle");
|
|
822
864
|
if (isLocked !== void 0) {
|
|
@@ -847,6 +889,9 @@ var DragHandlePlugin = ({
|
|
|
847
889
|
return value;
|
|
848
890
|
}
|
|
849
891
|
},
|
|
892
|
+
appendTransaction(_transactions, _oldState, newState) {
|
|
893
|
+
return buildRestoreTransaction(newState);
|
|
894
|
+
},
|
|
850
895
|
view: (view) => {
|
|
851
896
|
var _a;
|
|
852
897
|
element.draggable = true;
|
|
@@ -857,6 +902,7 @@ var DragHandlePlugin = ({
|
|
|
857
902
|
wrapper.style.position = "absolute";
|
|
858
903
|
wrapper.style.top = "0";
|
|
859
904
|
wrapper.style.left = "0";
|
|
905
|
+
wrapper.style.zIndex = "10";
|
|
860
906
|
element.addEventListener("dragstart", onDragStart);
|
|
861
907
|
element.addEventListener("dragend", onDragEnd);
|
|
862
908
|
document.addEventListener("drop", onDrop);
|