@tiptap/extension-drag-handle 3.27.1 → 3.27.2
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.js
CHANGED
|
@@ -278,28 +278,41 @@ function findBestDragTarget(view, coords, options) {
|
|
|
278
278
|
|
|
279
279
|
// src/helpers/findNextElementFromCursor.ts
|
|
280
280
|
function findClosestTopLevelBlock(element, view) {
|
|
281
|
+
var _a;
|
|
281
282
|
let current = element;
|
|
282
283
|
while ((current == null ? void 0 : current.parentElement) && current.parentElement !== view.dom) {
|
|
283
284
|
current = current.parentElement;
|
|
284
285
|
}
|
|
285
|
-
|
|
286
|
+
if ((current == null ? void 0 : current.parentElement) !== view.dom) {
|
|
287
|
+
return void 0;
|
|
288
|
+
}
|
|
289
|
+
if (!((_a = current.pmViewDesc) == null ? void 0 : _a.node)) {
|
|
290
|
+
return void 0;
|
|
291
|
+
}
|
|
292
|
+
return current;
|
|
286
293
|
}
|
|
287
294
|
function isValidRect(rect) {
|
|
288
295
|
return Number.isFinite(rect.top) && Number.isFinite(rect.bottom) && Number.isFinite(rect.left) && Number.isFinite(rect.right) && rect.width > 0 && rect.height > 0;
|
|
289
296
|
}
|
|
297
|
+
function edgeBlockRect(container, edge) {
|
|
298
|
+
let current = edge === "first" ? container.firstElementChild : container.lastElementChild;
|
|
299
|
+
while (current) {
|
|
300
|
+
const rect = current.getBoundingClientRect();
|
|
301
|
+
if (isValidRect(rect)) {
|
|
302
|
+
return rect;
|
|
303
|
+
}
|
|
304
|
+
current = edge === "first" ? current.nextElementSibling : current.previousElementSibling;
|
|
305
|
+
}
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
290
308
|
function clampToContent(view, x, y, inset = 5) {
|
|
291
309
|
if (!Number.isFinite(x) || !Number.isFinite(y)) {
|
|
292
310
|
return null;
|
|
293
311
|
}
|
|
294
312
|
const container = view.dom;
|
|
295
|
-
const
|
|
296
|
-
const
|
|
297
|
-
if (!
|
|
298
|
-
return null;
|
|
299
|
-
}
|
|
300
|
-
const topRect = firstBlock.getBoundingClientRect();
|
|
301
|
-
const botRect = lastBlock.getBoundingClientRect();
|
|
302
|
-
if (!isValidRect(topRect) || !isValidRect(botRect)) {
|
|
313
|
+
const topRect = edgeBlockRect(container, "first");
|
|
314
|
+
const botRect = edgeBlockRect(container, "last");
|
|
315
|
+
if (!topRect || !botRect) {
|
|
303
316
|
return null;
|
|
304
317
|
}
|
|
305
318
|
const clampedY = Math.min(Math.max(topRect.top + inset, y), botRect.bottom - inset);
|
|
@@ -532,8 +545,56 @@ function dragHandler(event, editor, nestedOptions, dragContext, dragImagePropert
|
|
|
532
545
|
document.addEventListener("dragend", cleanupDragPreview);
|
|
533
546
|
}
|
|
534
547
|
|
|
548
|
+
// src/helpers/getOuterNode.ts
|
|
549
|
+
var getOuterNodePos = (doc, pos) => {
|
|
550
|
+
const resolvedPos = doc.resolve(pos);
|
|
551
|
+
const { depth } = resolvedPos;
|
|
552
|
+
if (depth === 0) {
|
|
553
|
+
return pos;
|
|
554
|
+
}
|
|
555
|
+
const a = resolvedPos.pos - resolvedPos.parentOffset;
|
|
556
|
+
return a - 1;
|
|
557
|
+
};
|
|
558
|
+
var getOuterNode = (doc, pos) => {
|
|
559
|
+
const node = doc.nodeAt(pos);
|
|
560
|
+
const resolvedPos = doc.resolve(pos);
|
|
561
|
+
let { depth } = resolvedPos;
|
|
562
|
+
let parent = node;
|
|
563
|
+
while (depth > 0) {
|
|
564
|
+
const currentNode = resolvedPos.node(depth);
|
|
565
|
+
depth -= 1;
|
|
566
|
+
if (depth === 0) {
|
|
567
|
+
parent = currentNode;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
return parent;
|
|
571
|
+
};
|
|
572
|
+
|
|
535
573
|
// src/helpers/nodeRangeDrop.ts
|
|
536
574
|
import { isNodeRangeSelection, NodeRangeSelection as NodeRangeSelection2 } from "@tiptap/extension-node-range";
|
|
575
|
+
function mapPendingRestoreAnchor(pendingRestore, tr, options) {
|
|
576
|
+
if (!tr.docChanged) {
|
|
577
|
+
return pendingRestore;
|
|
578
|
+
}
|
|
579
|
+
if (options.isChangeOrigin && pendingRestore.relativeAnchorPos != null) {
|
|
580
|
+
const newPos = options.getAbsolutePos(pendingRestore.relativeAnchorPos);
|
|
581
|
+
if (!Number.isFinite(newPos) || newPos <= 0) {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
return {
|
|
585
|
+
...pendingRestore,
|
|
586
|
+
anchorPos: newPos
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1);
|
|
590
|
+
if (mappedResult.deleted) {
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
return {
|
|
594
|
+
...pendingRestore,
|
|
595
|
+
anchorPos: mappedResult.pos
|
|
596
|
+
};
|
|
597
|
+
}
|
|
537
598
|
function sumNodeSizes(parent, from, to) {
|
|
538
599
|
let size = 0;
|
|
539
600
|
for (let i = from; i < to; i += 1) {
|
|
@@ -580,31 +641,6 @@ function createDroppedNodeRangeSelection(doc, anchorPos, nodeCount, depth) {
|
|
|
580
641
|
}
|
|
581
642
|
}
|
|
582
643
|
|
|
583
|
-
// src/helpers/getOuterNode.ts
|
|
584
|
-
var getOuterNodePos = (doc, pos) => {
|
|
585
|
-
const resolvedPos = doc.resolve(pos);
|
|
586
|
-
const { depth } = resolvedPos;
|
|
587
|
-
if (depth === 0) {
|
|
588
|
-
return pos;
|
|
589
|
-
}
|
|
590
|
-
const a = resolvedPos.pos - resolvedPos.parentOffset;
|
|
591
|
-
return a - 1;
|
|
592
|
-
};
|
|
593
|
-
var getOuterNode = (doc, pos) => {
|
|
594
|
-
const node = doc.nodeAt(pos);
|
|
595
|
-
const resolvedPos = doc.resolve(pos);
|
|
596
|
-
let { depth } = resolvedPos;
|
|
597
|
-
let parent = node;
|
|
598
|
-
while (depth > 0) {
|
|
599
|
-
const currentNode = resolvedPos.node(depth);
|
|
600
|
-
depth -= 1;
|
|
601
|
-
if (depth === 0) {
|
|
602
|
-
parent = currentNode;
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
return parent;
|
|
606
|
-
};
|
|
607
|
-
|
|
608
644
|
// src/drag-handle-plugin.ts
|
|
609
645
|
var getRelativePos = (state, absolutePos) => {
|
|
610
646
|
const ystate = ySyncPluginKey.getState(state);
|
|
@@ -654,10 +690,40 @@ var DragHandlePlugin = ({
|
|
|
654
690
|
let currentNodePos = -1;
|
|
655
691
|
let currentNodeRelPos;
|
|
656
692
|
let rafId = null;
|
|
657
|
-
let restoreRafId = null;
|
|
658
693
|
let pendingMouseCoords = null;
|
|
659
694
|
let activeDragRange = null;
|
|
660
695
|
let pendingRestore = null;
|
|
696
|
+
function clearDragRangeState() {
|
|
697
|
+
activeDragRange = null;
|
|
698
|
+
pendingRestore = null;
|
|
699
|
+
}
|
|
700
|
+
function remapPendingRestore(tr, state) {
|
|
701
|
+
if (!pendingRestore) {
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
pendingRestore = mapPendingRestoreAnchor(pendingRestore, tr, {
|
|
705
|
+
isChangeOrigin: isChangeOrigin(tr),
|
|
706
|
+
getAbsolutePos: (relativePos) => getAbsolutePos(state, relativePos)
|
|
707
|
+
});
|
|
708
|
+
}
|
|
709
|
+
function buildRestoreTransaction(state) {
|
|
710
|
+
if (!pendingRestore) {
|
|
711
|
+
return null;
|
|
712
|
+
}
|
|
713
|
+
const nodeRangeSelection = createDroppedNodeRangeSelection(
|
|
714
|
+
state.doc,
|
|
715
|
+
pendingRestore.anchorPos,
|
|
716
|
+
pendingRestore.nodeCount,
|
|
717
|
+
pendingRestore.depth
|
|
718
|
+
);
|
|
719
|
+
if (!nodeRangeSelection) {
|
|
720
|
+
pendingRestore = null;
|
|
721
|
+
activeDragRange = null;
|
|
722
|
+
return null;
|
|
723
|
+
}
|
|
724
|
+
clearDragRangeState();
|
|
725
|
+
return state.tr.setSelection(nodeRangeSelection);
|
|
726
|
+
}
|
|
661
727
|
function hideHandle() {
|
|
662
728
|
if (!element) {
|
|
663
729
|
return;
|
|
@@ -716,17 +782,6 @@ var DragHandlePlugin = ({
|
|
|
716
782
|
element.dataset.dragging = "false";
|
|
717
783
|
}
|
|
718
784
|
}
|
|
719
|
-
function restoreNodeRangeSelection({ nodeCount, depth, anchorPos }) {
|
|
720
|
-
const nodeRangeSelection = createDroppedNodeRangeSelection(
|
|
721
|
-
editor.state.doc,
|
|
722
|
-
anchorPos,
|
|
723
|
-
nodeCount,
|
|
724
|
-
depth
|
|
725
|
-
);
|
|
726
|
-
if (nodeRangeSelection) {
|
|
727
|
-
editor.view.dispatch(editor.state.tr.setSelection(nodeRangeSelection));
|
|
728
|
-
}
|
|
729
|
-
}
|
|
730
785
|
function onDrop(e) {
|
|
731
786
|
if (!e.target || !editor.view.dom.contains(e.target)) {
|
|
732
787
|
return;
|
|
@@ -743,17 +798,14 @@ var DragHandlePlugin = ({
|
|
|
743
798
|
if (!activeDragRange || editor.view.state.selection.empty) {
|
|
744
799
|
return;
|
|
745
800
|
}
|
|
801
|
+
const anchorPos = editor.state.selection.from;
|
|
802
|
+
const relativeAnchorPos = getRelativePos(editor.state, anchorPos);
|
|
746
803
|
pendingRestore = {
|
|
747
804
|
...activeDragRange,
|
|
748
|
-
anchorPos
|
|
805
|
+
anchorPos,
|
|
806
|
+
relativeAnchorPos: relativeAnchorPos != null ? relativeAnchorPos : void 0
|
|
749
807
|
};
|
|
750
|
-
|
|
751
|
-
restoreRafId = null;
|
|
752
|
-
if (pendingRestore) {
|
|
753
|
-
restoreNodeRangeSelection(pendingRestore);
|
|
754
|
-
pendingRestore = null;
|
|
755
|
-
}
|
|
756
|
-
});
|
|
808
|
+
editor.view.dispatch(editor.state.tr.setMeta("addToHistory", false));
|
|
757
809
|
}
|
|
758
810
|
function cleanup() {
|
|
759
811
|
element.removeEventListener("dragstart", onDragStart);
|
|
@@ -764,10 +816,7 @@ var DragHandlePlugin = ({
|
|
|
764
816
|
rafId = null;
|
|
765
817
|
pendingMouseCoords = null;
|
|
766
818
|
}
|
|
767
|
-
|
|
768
|
-
cancelAnimationFrame(restoreRafId);
|
|
769
|
-
restoreRafId = null;
|
|
770
|
-
}
|
|
819
|
+
clearDragRangeState();
|
|
771
820
|
}
|
|
772
821
|
wrapper.appendChild(element);
|
|
773
822
|
return {
|
|
@@ -781,14 +830,7 @@ var DragHandlePlugin = ({
|
|
|
781
830
|
return { locked: false };
|
|
782
831
|
},
|
|
783
832
|
apply(tr, value, _oldState, state) {
|
|
784
|
-
|
|
785
|
-
const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1);
|
|
786
|
-
if (mappedResult.deleted) {
|
|
787
|
-
pendingRestore = null;
|
|
788
|
-
} else {
|
|
789
|
-
pendingRestore.anchorPos = mappedResult.pos;
|
|
790
|
-
}
|
|
791
|
-
}
|
|
833
|
+
remapPendingRestore(tr, state);
|
|
792
834
|
const isLocked = tr.getMeta("lockDragHandle");
|
|
793
835
|
const hideDragHandle = tr.getMeta("hideDragHandle");
|
|
794
836
|
if (isLocked !== void 0) {
|
|
@@ -819,6 +861,9 @@ var DragHandlePlugin = ({
|
|
|
819
861
|
return value;
|
|
820
862
|
}
|
|
821
863
|
},
|
|
864
|
+
appendTransaction(_transactions, _oldState, newState) {
|
|
865
|
+
return buildRestoreTransaction(newState);
|
|
866
|
+
},
|
|
822
867
|
view: (view) => {
|
|
823
868
|
var _a;
|
|
824
869
|
element.draggable = true;
|
|
@@ -829,6 +874,7 @@ var DragHandlePlugin = ({
|
|
|
829
874
|
wrapper.style.position = "absolute";
|
|
830
875
|
wrapper.style.top = "0";
|
|
831
876
|
wrapper.style.left = "0";
|
|
877
|
+
wrapper.style.zIndex = "10";
|
|
832
878
|
element.addEventListener("dragstart", onDragStart);
|
|
833
879
|
element.addEventListener("dragend", onDragEnd);
|
|
834
880
|
document.addEventListener("drop", onDrop);
|