@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.cjs CHANGED
@@ -48,7 +48,7 @@ var import_state = require("@tiptap/pm/state");
48
48
  function getCSSText(element, properties) {
49
49
  const style = getComputedStyle(element);
50
50
  if (properties) {
51
- return properties.filter((p) => p.trim().length > 0).map((p) => `${p}:${style.getPropertyValue(p)};`).join("");
51
+ return properties.map((property) => property.trim()).filter((property) => property.length > 0).map((property) => `${property}:${style.getPropertyValue(property)};`).join("");
52
52
  }
53
53
  let value = "";
54
54
  for (let i = 0; i < style.length; i += 1) {
@@ -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
- return (current == null ? void 0 : current.parentElement) === view.dom ? current : void 0;
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 firstBlock = container.firstElementChild;
324
- const lastBlock = container.lastElementChild;
325
- if (!firstBlock || !lastBlock) {
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);
@@ -453,6 +466,15 @@ function removeNode(node) {
453
466
  function getDragImageOffset(direction, wrapperWidth) {
454
467
  return direction === "rtl" ? wrapperWidth : 0;
455
468
  }
469
+ function shouldResetMargin(dragImageProperties) {
470
+ if (!dragImageProperties) {
471
+ return true;
472
+ }
473
+ return !dragImageProperties.some((property) => {
474
+ const p = property.trim().toLowerCase();
475
+ return p === "margin" || p.startsWith("margin-");
476
+ });
477
+ }
456
478
  function getDragHandleRanges(event, editor, nestedOptions, dragContext) {
457
479
  const { doc } = editor.view.state;
458
480
  if ((nestedOptions == null ? void 0 : nestedOptions.enabled) && (dragContext == null ? void 0 : dragContext.node) && dragContext.pos >= 0) {
@@ -514,13 +536,16 @@ function dragHandler(event, editor, nestedOptions, dragContext, dragImagePropert
514
536
  selection = import_extension_node_range.NodeRangeSelection.create(view.state.doc, from, to);
515
537
  slice = selection.content();
516
538
  }
539
+ const resetMargin = shouldResetMargin(dragImageProperties);
517
540
  ranges.forEach((range) => {
518
541
  const element = getDraggedBlockElement(view, range.$from.pos);
519
542
  if (!element) {
520
543
  return;
521
544
  }
522
545
  const clonedElement = cloneElement(element, dragImageProperties);
523
- clonedElement.style.margin = "0";
546
+ if (resetMargin) {
547
+ clonedElement.style.margin = "0";
548
+ }
524
549
  wrapper.append(clonedElement);
525
550
  });
526
551
  wrapper.style.position = "absolute";
@@ -548,8 +573,56 @@ function dragHandler(event, editor, nestedOptions, dragContext, dragImagePropert
548
573
  document.addEventListener("dragend", cleanupDragPreview);
549
574
  }
550
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
+
551
601
  // src/helpers/nodeRangeDrop.ts
552
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
+ }
553
626
  function sumNodeSizes(parent, from, to) {
554
627
  let size = 0;
555
628
  for (let i = from; i < to; i += 1) {
@@ -596,31 +669,6 @@ function createDroppedNodeRangeSelection(doc, anchorPos, nodeCount, depth) {
596
669
  }
597
670
  }
598
671
 
599
- // src/helpers/getOuterNode.ts
600
- var getOuterNodePos = (doc, pos) => {
601
- const resolvedPos = doc.resolve(pos);
602
- const { depth } = resolvedPos;
603
- if (depth === 0) {
604
- return pos;
605
- }
606
- const a = resolvedPos.pos - resolvedPos.parentOffset;
607
- return a - 1;
608
- };
609
- var getOuterNode = (doc, pos) => {
610
- const node = doc.nodeAt(pos);
611
- const resolvedPos = doc.resolve(pos);
612
- let { depth } = resolvedPos;
613
- let parent = node;
614
- while (depth > 0) {
615
- const currentNode = resolvedPos.node(depth);
616
- depth -= 1;
617
- if (depth === 0) {
618
- parent = currentNode;
619
- }
620
- }
621
- return parent;
622
- };
623
-
624
672
  // src/drag-handle-plugin.ts
625
673
  var getRelativePos = (state, absolutePos) => {
626
674
  const ystate = import_y_tiptap.ySyncPluginKey.getState(state);
@@ -670,10 +718,40 @@ var DragHandlePlugin = ({
670
718
  let currentNodePos = -1;
671
719
  let currentNodeRelPos;
672
720
  let rafId = null;
673
- let restoreRafId = null;
674
721
  let pendingMouseCoords = null;
675
722
  let activeDragRange = null;
676
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
+ }
677
755
  function hideHandle() {
678
756
  if (!element) {
679
757
  return;
@@ -732,17 +810,6 @@ var DragHandlePlugin = ({
732
810
  element.dataset.dragging = "false";
733
811
  }
734
812
  }
735
- function restoreNodeRangeSelection({ nodeCount, depth, anchorPos }) {
736
- const nodeRangeSelection = createDroppedNodeRangeSelection(
737
- editor.state.doc,
738
- anchorPos,
739
- nodeCount,
740
- depth
741
- );
742
- if (nodeRangeSelection) {
743
- editor.view.dispatch(editor.state.tr.setSelection(nodeRangeSelection));
744
- }
745
- }
746
813
  function onDrop(e) {
747
814
  if (!e.target || !editor.view.dom.contains(e.target)) {
748
815
  return;
@@ -759,17 +826,14 @@ var DragHandlePlugin = ({
759
826
  if (!activeDragRange || editor.view.state.selection.empty) {
760
827
  return;
761
828
  }
829
+ const anchorPos = editor.state.selection.from;
830
+ const relativeAnchorPos = getRelativePos(editor.state, anchorPos);
762
831
  pendingRestore = {
763
832
  ...activeDragRange,
764
- anchorPos: editor.state.selection.from
833
+ anchorPos,
834
+ relativeAnchorPos: relativeAnchorPos != null ? relativeAnchorPos : void 0
765
835
  };
766
- restoreRafId = requestAnimationFrame(() => {
767
- restoreRafId = null;
768
- if (pendingRestore) {
769
- restoreNodeRangeSelection(pendingRestore);
770
- pendingRestore = null;
771
- }
772
- });
836
+ editor.view.dispatch(editor.state.tr.setMeta("addToHistory", false));
773
837
  }
774
838
  function cleanup() {
775
839
  element.removeEventListener("dragstart", onDragStart);
@@ -780,10 +844,7 @@ var DragHandlePlugin = ({
780
844
  rafId = null;
781
845
  pendingMouseCoords = null;
782
846
  }
783
- if (restoreRafId) {
784
- cancelAnimationFrame(restoreRafId);
785
- restoreRafId = null;
786
- }
847
+ clearDragRangeState();
787
848
  }
788
849
  wrapper.appendChild(element);
789
850
  return {
@@ -797,14 +858,7 @@ var DragHandlePlugin = ({
797
858
  return { locked: false };
798
859
  },
799
860
  apply(tr, value, _oldState, state) {
800
- if (pendingRestore && tr.docChanged) {
801
- const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1);
802
- if (mappedResult.deleted) {
803
- pendingRestore = null;
804
- } else {
805
- pendingRestore.anchorPos = mappedResult.pos;
806
- }
807
- }
861
+ remapPendingRestore(tr, state);
808
862
  const isLocked = tr.getMeta("lockDragHandle");
809
863
  const hideDragHandle = tr.getMeta("hideDragHandle");
810
864
  if (isLocked !== void 0) {
@@ -835,6 +889,9 @@ var DragHandlePlugin = ({
835
889
  return value;
836
890
  }
837
891
  },
892
+ appendTransaction(_transactions, _oldState, newState) {
893
+ return buildRestoreTransaction(newState);
894
+ },
838
895
  view: (view) => {
839
896
  var _a;
840
897
  element.draggable = true;
@@ -845,6 +902,7 @@ var DragHandlePlugin = ({
845
902
  wrapper.style.position = "absolute";
846
903
  wrapper.style.top = "0";
847
904
  wrapper.style.left = "0";
905
+ wrapper.style.zIndex = "10";
848
906
  element.addEventListener("dragstart", onDragStart);
849
907
  element.addEventListener("dragend", onDragEnd);
850
908
  document.addEventListener("drop", onDrop);