@tiptap/extension-drag-handle 3.27.0 → 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.js CHANGED
@@ -20,7 +20,7 @@ import { NodeSelection } from "@tiptap/pm/state";
20
20
  function getCSSText(element, properties) {
21
21
  const style = getComputedStyle(element);
22
22
  if (properties) {
23
- return properties.filter((p) => p.trim().length > 0).map((p) => `${p}:${style.getPropertyValue(p)};`).join("");
23
+ return properties.map((property) => property.trim()).filter((property) => property.length > 0).map((property) => `${property}:${style.getPropertyValue(property)};`).join("");
24
24
  }
25
25
  let value = "";
26
26
  for (let i = 0; i < style.length; i += 1) {
@@ -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
- return (current == null ? void 0 : current.parentElement) === view.dom ? current : void 0;
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 firstBlock = container.firstElementChild;
296
- const lastBlock = container.lastElementChild;
297
- if (!firstBlock || !lastBlock) {
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);
@@ -425,6 +438,15 @@ function removeNode(node) {
425
438
  function getDragImageOffset(direction, wrapperWidth) {
426
439
  return direction === "rtl" ? wrapperWidth : 0;
427
440
  }
441
+ function shouldResetMargin(dragImageProperties) {
442
+ if (!dragImageProperties) {
443
+ return true;
444
+ }
445
+ return !dragImageProperties.some((property) => {
446
+ const p = property.trim().toLowerCase();
447
+ return p === "margin" || p.startsWith("margin-");
448
+ });
449
+ }
428
450
  function getDragHandleRanges(event, editor, nestedOptions, dragContext) {
429
451
  const { doc } = editor.view.state;
430
452
  if ((nestedOptions == null ? void 0 : nestedOptions.enabled) && (dragContext == null ? void 0 : dragContext.node) && dragContext.pos >= 0) {
@@ -486,13 +508,16 @@ function dragHandler(event, editor, nestedOptions, dragContext, dragImagePropert
486
508
  selection = NodeRangeSelection.create(view.state.doc, from, to);
487
509
  slice = selection.content();
488
510
  }
511
+ const resetMargin = shouldResetMargin(dragImageProperties);
489
512
  ranges.forEach((range) => {
490
513
  const element = getDraggedBlockElement(view, range.$from.pos);
491
514
  if (!element) {
492
515
  return;
493
516
  }
494
517
  const clonedElement = cloneElement(element, dragImageProperties);
495
- clonedElement.style.margin = "0";
518
+ if (resetMargin) {
519
+ clonedElement.style.margin = "0";
520
+ }
496
521
  wrapper.append(clonedElement);
497
522
  });
498
523
  wrapper.style.position = "absolute";
@@ -520,8 +545,56 @@ function dragHandler(event, editor, nestedOptions, dragContext, dragImagePropert
520
545
  document.addEventListener("dragend", cleanupDragPreview);
521
546
  }
522
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
+
523
573
  // src/helpers/nodeRangeDrop.ts
524
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
+ }
525
598
  function sumNodeSizes(parent, from, to) {
526
599
  let size = 0;
527
600
  for (let i = from; i < to; i += 1) {
@@ -568,31 +641,6 @@ function createDroppedNodeRangeSelection(doc, anchorPos, nodeCount, depth) {
568
641
  }
569
642
  }
570
643
 
571
- // src/helpers/getOuterNode.ts
572
- var getOuterNodePos = (doc, pos) => {
573
- const resolvedPos = doc.resolve(pos);
574
- const { depth } = resolvedPos;
575
- if (depth === 0) {
576
- return pos;
577
- }
578
- const a = resolvedPos.pos - resolvedPos.parentOffset;
579
- return a - 1;
580
- };
581
- var getOuterNode = (doc, pos) => {
582
- const node = doc.nodeAt(pos);
583
- const resolvedPos = doc.resolve(pos);
584
- let { depth } = resolvedPos;
585
- let parent = node;
586
- while (depth > 0) {
587
- const currentNode = resolvedPos.node(depth);
588
- depth -= 1;
589
- if (depth === 0) {
590
- parent = currentNode;
591
- }
592
- }
593
- return parent;
594
- };
595
-
596
644
  // src/drag-handle-plugin.ts
597
645
  var getRelativePos = (state, absolutePos) => {
598
646
  const ystate = ySyncPluginKey.getState(state);
@@ -642,10 +690,40 @@ var DragHandlePlugin = ({
642
690
  let currentNodePos = -1;
643
691
  let currentNodeRelPos;
644
692
  let rafId = null;
645
- let restoreRafId = null;
646
693
  let pendingMouseCoords = null;
647
694
  let activeDragRange = null;
648
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
+ }
649
727
  function hideHandle() {
650
728
  if (!element) {
651
729
  return;
@@ -704,17 +782,6 @@ var DragHandlePlugin = ({
704
782
  element.dataset.dragging = "false";
705
783
  }
706
784
  }
707
- function restoreNodeRangeSelection({ nodeCount, depth, anchorPos }) {
708
- const nodeRangeSelection = createDroppedNodeRangeSelection(
709
- editor.state.doc,
710
- anchorPos,
711
- nodeCount,
712
- depth
713
- );
714
- if (nodeRangeSelection) {
715
- editor.view.dispatch(editor.state.tr.setSelection(nodeRangeSelection));
716
- }
717
- }
718
785
  function onDrop(e) {
719
786
  if (!e.target || !editor.view.dom.contains(e.target)) {
720
787
  return;
@@ -731,17 +798,14 @@ var DragHandlePlugin = ({
731
798
  if (!activeDragRange || editor.view.state.selection.empty) {
732
799
  return;
733
800
  }
801
+ const anchorPos = editor.state.selection.from;
802
+ const relativeAnchorPos = getRelativePos(editor.state, anchorPos);
734
803
  pendingRestore = {
735
804
  ...activeDragRange,
736
- anchorPos: editor.state.selection.from
805
+ anchorPos,
806
+ relativeAnchorPos: relativeAnchorPos != null ? relativeAnchorPos : void 0
737
807
  };
738
- restoreRafId = requestAnimationFrame(() => {
739
- restoreRafId = null;
740
- if (pendingRestore) {
741
- restoreNodeRangeSelection(pendingRestore);
742
- pendingRestore = null;
743
- }
744
- });
808
+ editor.view.dispatch(editor.state.tr.setMeta("addToHistory", false));
745
809
  }
746
810
  function cleanup() {
747
811
  element.removeEventListener("dragstart", onDragStart);
@@ -752,10 +816,7 @@ var DragHandlePlugin = ({
752
816
  rafId = null;
753
817
  pendingMouseCoords = null;
754
818
  }
755
- if (restoreRafId) {
756
- cancelAnimationFrame(restoreRafId);
757
- restoreRafId = null;
758
- }
819
+ clearDragRangeState();
759
820
  }
760
821
  wrapper.appendChild(element);
761
822
  return {
@@ -769,14 +830,7 @@ var DragHandlePlugin = ({
769
830
  return { locked: false };
770
831
  },
771
832
  apply(tr, value, _oldState, state) {
772
- if (pendingRestore && tr.docChanged) {
773
- const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1);
774
- if (mappedResult.deleted) {
775
- pendingRestore = null;
776
- } else {
777
- pendingRestore.anchorPos = mappedResult.pos;
778
- }
779
- }
833
+ remapPendingRestore(tr, state);
780
834
  const isLocked = tr.getMeta("lockDragHandle");
781
835
  const hideDragHandle = tr.getMeta("hideDragHandle");
782
836
  if (isLocked !== void 0) {
@@ -807,6 +861,9 @@ var DragHandlePlugin = ({
807
861
  return value;
808
862
  }
809
863
  },
864
+ appendTransaction(_transactions, _oldState, newState) {
865
+ return buildRestoreTransaction(newState);
866
+ },
810
867
  view: (view) => {
811
868
  var _a;
812
869
  element.draggable = true;
@@ -817,6 +874,7 @@ var DragHandlePlugin = ({
817
874
  wrapper.style.position = "absolute";
818
875
  wrapper.style.top = "0";
819
876
  wrapper.style.left = "0";
877
+ wrapper.style.zIndex = "10";
820
878
  element.addEventListener("dragstart", onDragStart);
821
879
  element.addEventListener("dragend", onDragEnd);
822
880
  document.addEventListener("drop", onDrop);