{"version":3,"sources":["../src/index.ts","../src/drag-handle.ts","../src/drag-handle-plugin.ts","../src/helpers/dragHandler.ts","../src/helpers/cloneElement.ts","../src/helpers/defaultRules.ts","../src/helpers/edgeDetection.ts","../src/helpers/scoring.ts","../src/helpers/findBestDragTarget.ts","../src/helpers/findNextElementFromCursor.ts","../src/helpers/getDraggedBlockDir.ts","../src/helpers/removeNode.ts","../src/helpers/nodeRangeDrop.ts","../src/helpers/getOuterNode.ts","../src/helpers/normalizeOptions.ts"],"sourcesContent":["import { DragHandle } from './drag-handle.js'\n\nexport * from './drag-handle.js'\nexport * from './drag-handle-plugin.js'\nexport { defaultRules } from './helpers/defaultRules.js'\nexport { normalizeNestedOptions } from './helpers/normalizeOptions.js'\nexport type {\n  EdgeDetectionConfig,\n  EdgeDetectionPreset,\n  NestedOptions,\n  NormalizedNestedOptions,\n} from './types/options.js'\nexport type { DragHandleRule, RuleContext } from './types/rules.js'\n\nexport default DragHandle\n","import type { ComputePositionConfig, VirtualElement } from '@floating-ui/dom'\nimport { type Editor, Extension } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\n\nimport { DragHandlePlugin } from './drag-handle-plugin.js'\nimport { normalizeNestedOptions } from './helpers/normalizeOptions.js'\nimport type { NestedOptions } from './types/options.js'\n\nexport const defaultComputePositionConfig: ComputePositionConfig = {\n  placement: 'left-start',\n  strategy: 'absolute',\n}\n\nexport interface DragHandleOptions {\n  /**\n   * Renders an element that is positioned with the floating-ui/dom package\n   */\n  render(): HTMLElement\n  /**\n   * Configuration for position computation of the drag handle\n   * using the floating-ui/dom package\n   */\n  computePositionConfig?: ComputePositionConfig\n  /**\n   * A function that returns the virtual element for the drag handle.\n   * This is useful when the menu needs to be positioned relative to a specific DOM element.\n   */\n  getReferencedVirtualElement?: () => VirtualElement | null\n  /**\n   * Locks the draghandle in place and visibility\n   */\n  locked?: boolean\n  /**\n   * Returns a node or null when a node is hovered over\n   */\n  onNodeChange?: (options: { node: Node | null; editor: Editor }) => void\n  /**\n   * The callback function that will be called when drag start.\n   */\n  onElementDragStart?: (e: DragEvent) => void\n  /**\n   * The callback function that will be called when drag end.\n   */\n  onElementDragEnd?: (e: DragEvent) => void\n  /**\n   * Enable drag handles for nested content (list items, blockquotes, etc.).\n   *\n   * When enabled, the drag handle appears for block nodes at any depth, not just\n   * top-level blocks. A rule-based scoring system evaluates all ancestor nodes\n   * at the cursor position and selects the best drag target.\n   *\n   * **Values:**\n   * - `false` (default): Only root-level blocks show drag handles\n   * - `true`: Enable with sensible defaults (left edge detection, default rules)\n   * - `NestedOptions`: Enable with full custom configuration\n   *\n   * @default false\n   *\n   * @example\n   * // Simple enable with sensible defaults\n   * DragHandle.configure({\n   *   nested: true,\n   * })\n   *\n   * @example\n   * // Restrict to specific containers\n   * DragHandle.configure({\n   *   nested: {\n   *     allowedContainers: ['bulletList', 'orderedList'],\n   *   },\n   * })\n   *\n   * @example\n   * // With custom rules and edge detection disabled\n   * DragHandle.configure({\n   *   nested: {\n   *     rules: [{\n   *       id: 'excludeCodeBlocks',\n   *       evaluate: ({ node }) => node.type.name === 'codeBlock' ? 1000 : 0,\n   *     }],\n   *     edgeDetection: 'none',\n   *   },\n   * })\n   *\n   * @example\n   * // Full configuration\n   * DragHandle.configure({\n   *   nested: {\n   *     defaultRules: true,\n   *     allowedContainers: ['bulletList', 'orderedList', 'blockquote'],\n   *     edgeDetection: { threshold: 20 },\n   *     rules: [{\n   *       id: 'preferShallow',\n   *       evaluate: ({ depth }) => depth * 200,\n   *     }],\n   *   },\n   * })\n   */\n  nested?: boolean | NestedOptions\n  /**\n   * Limit the drag image clone to a subset of CSS properties instead of\n   * copying all computed styles. When set, only the listed properties\n   * are read from `getComputedStyle` and applied to the drag image clone.\n   *\n   * Useful for improving drag performance on selections containing complex\n   * or deeply nested nodes.\n   *\n   * @example\n   * // Only copy visual appearance, skip layout properties\n   * DragHandle.configure({\n   *   dragImageProperties: ['color', 'background-color', 'font-size', 'font-family'],\n   * })\n   */\n  dragImageProperties?: string[]\n}\n\ndeclare module '@tiptap/core' {\n  interface Commands<ReturnType> {\n    dragHandle: {\n      /**\n       * Locks the draghandle in place and visibility\n       */\n      lockDragHandle: () => ReturnType\n      /**\n       * Unlocks the draghandle\n       */\n      unlockDragHandle: () => ReturnType\n      /**\n       * Toggle draghandle lock state\n       */\n      toggleDragHandle: () => ReturnType\n    }\n  }\n}\n\nexport const DragHandle = Extension.create<DragHandleOptions>({\n  name: 'dragHandle',\n\n  addOptions() {\n    return {\n      render() {\n        const element = document.createElement('div')\n\n        element.classList.add('drag-handle')\n\n        return element\n      },\n      computePositionConfig: {},\n      locked: false,\n      onNodeChange: () => {\n        return null\n      },\n      onElementDragStart: undefined,\n      onElementDragEnd: undefined,\n      nested: false,\n      dragImageProperties: undefined,\n    }\n  },\n\n  addCommands() {\n    return {\n      lockDragHandle:\n        () =>\n        ({ editor }) => {\n          this.options.locked = true\n          return editor.commands.setMeta('lockDragHandle', this.options.locked)\n        },\n      unlockDragHandle:\n        () =>\n        ({ editor }) => {\n          this.options.locked = false\n          return editor.commands.setMeta('lockDragHandle', this.options.locked)\n        },\n      toggleDragHandle:\n        () =>\n        ({ editor }) => {\n          this.options.locked = !this.options.locked\n          return editor.commands.setMeta('lockDragHandle', this.options.locked)\n        },\n    }\n  },\n\n  addProseMirrorPlugins() {\n    const element = this.options.render()\n    const nestedOptions = normalizeNestedOptions(this.options.nested)\n\n    return [\n      DragHandlePlugin({\n        computePositionConfig: {\n          ...defaultComputePositionConfig,\n          ...this.options.computePositionConfig,\n        },\n        getReferencedVirtualElement: this.options.getReferencedVirtualElement,\n        element,\n        editor: this.editor,\n        onNodeChange: this.options.onNodeChange,\n        onElementDragStart: this.options.onElementDragStart,\n        onElementDragEnd: this.options.onElementDragEnd,\n        nestedOptions,\n        dragImageProperties: this.options.dragImageProperties,\n      }).plugin,\n    ]\n  },\n})\n","import { type ComputePositionConfig, type VirtualElement, computePosition } from '@floating-ui/dom'\nimport { type Editor, isFirefox } from '@tiptap/core'\nimport { isChangeOrigin } from '@tiptap/extension-collaboration'\nimport type { Node } from '@tiptap/pm/model'\nimport { type EditorState, type Transaction, Plugin, PluginKey, Selection } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport {\n  absolutePositionToRelativePosition,\n  relativePositionToAbsolutePosition,\n  ySyncPluginKey,\n} from '@tiptap/y-tiptap'\n\nimport { dragHandler } from './helpers/dragHandler.js'\nimport { findElementNextToCoords } from './helpers/findNextElementFromCursor.js'\nimport {\n  type ActiveDragRange,\n  createDroppedNodeRangeSelection,\n  getActiveDragRange,\n} from './helpers/nodeRangeDrop.js'\nimport { getOuterNode, getOuterNodePos } from './helpers/getOuterNode.js'\nimport { removeNode } from './helpers/removeNode.js'\nimport type { NormalizedNestedOptions } from './types/options.js'\n\ntype PluginState = {\n  locked: boolean\n}\n\nconst getRelativePos = (state: EditorState, absolutePos: number) => {\n  const ystate = ySyncPluginKey.getState(state)\n\n  if (!ystate) {\n    return null\n  }\n\n  return absolutePositionToRelativePosition(absolutePos, ystate.type, ystate.binding.mapping)\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: y-prosemirror (and y-tiptap by extension) does not have types for relative positions\nconst getAbsolutePos = (state: EditorState, relativePos: any) => {\n  const ystate = ySyncPluginKey.getState(state)\n\n  if (!ystate) {\n    return -1\n  }\n\n  return (\n    relativePositionToAbsolutePosition(\n      ystate.doc,\n      ystate.type,\n      relativePos,\n      ystate.binding.mapping,\n    ) || 0\n  )\n}\n\nconst getOuterDomNode = (view: EditorView, domNode: HTMLElement) => {\n  let tmpDomNode = domNode\n\n  // Traverse to top level node.\n  while (tmpDomNode?.parentNode) {\n    if (tmpDomNode.parentNode === view.dom) {\n      break\n    }\n\n    tmpDomNode = tmpDomNode.parentNode as HTMLElement\n  }\n\n  return tmpDomNode\n}\n\nexport interface DragHandlePluginProps {\n  pluginKey?: PluginKey | string\n  editor: Editor\n  element: HTMLElement\n  onNodeChange?: (data: { editor: Editor; node: Node | null; pos: number }) => void\n  onElementDragStart?: (e: DragEvent) => void\n  onElementDragEnd?: (e: DragEvent) => void\n  computePositionConfig?: ComputePositionConfig\n  getReferencedVirtualElement?: () => VirtualElement | null\n  nestedOptions: NormalizedNestedOptions\n  dragImageProperties?: string[]\n}\n\nexport const dragHandlePluginDefaultKey = new PluginKey('dragHandle')\n\nexport const DragHandlePlugin = ({\n  pluginKey = dragHandlePluginDefaultKey,\n  element,\n  editor,\n  computePositionConfig,\n  getReferencedVirtualElement,\n  onNodeChange,\n  onElementDragStart,\n  onElementDragEnd,\n  nestedOptions,\n  dragImageProperties,\n}: DragHandlePluginProps) => {\n  const wrapper = document.createElement('div')\n  let locked = false\n  let currentNode: Node | null = null\n  let currentNodePos = -1\n  // biome-ignore lint/suspicious/noExplicitAny: See above - relative positions in y-prosemirror are not typed\n  let currentNodeRelPos: any\n  let rafId: number | null = null\n  let restoreRafId: number | null = null\n  let pendingMouseCoords: { x: number; y: number } | null = null\n  let activeDragRange: ActiveDragRange | null = null\n  let pendingRestore: ActiveDragRange | null = null\n\n  function hideHandle() {\n    if (!element) {\n      return\n    }\n\n    element.style.visibility = 'hidden'\n    element.style.pointerEvents = 'none'\n  }\n\n  function showHandle() {\n    if (!element) {\n      return\n    }\n\n    if (!editor.isEditable) {\n      hideHandle()\n      return\n    }\n\n    element.style.visibility = ''\n    element.style.pointerEvents = 'auto'\n  }\n\n  function repositionDragHandle(dom: Element) {\n    const virtualElement = getReferencedVirtualElement?.() || {\n      getBoundingClientRect: () => dom.getBoundingClientRect(),\n    }\n\n    computePosition(virtualElement, element, computePositionConfig).then(val => {\n      Object.assign(element.style, {\n        position: val.strategy,\n        left: `${val.x}px`,\n        top: `${val.y}px`,\n      })\n    })\n  }\n\n  function onDragStart(e: DragEvent) {\n    onElementDragStart?.(e)\n    // Push this to the end of the event cue\n    // Fixes bug where incorrect drag pos is returned if drag handle has position: absolute\n    // Pass the current node context to avoid recalculation issues during drag start\n    dragHandler(\n      e,\n      editor,\n      nestedOptions,\n      { node: currentNode, pos: currentNodePos },\n      dragImageProperties,\n    )\n\n    // remember a multi-block node range so it can be restored after drop\n    activeDragRange = getActiveDragRange(editor.state.selection)\n\n    if (element) {\n      element.dataset.dragging = 'true'\n    }\n\n    setTimeout(() => {\n      if (element) {\n        element.style.pointerEvents = 'none'\n      }\n    }, 0)\n  }\n\n  function onDragEnd(e: DragEvent) {\n    onElementDragEnd?.(e)\n    activeDragRange = null\n    hideHandle()\n    if (element) {\n      element.style.pointerEvents = 'auto'\n      element.dataset.dragging = 'false'\n    }\n  }\n\n  // ProseMirror leaves a TextSelection inside the dropped content, so rebuild the\n  // node range over the freshly dropped blocks to keep the selection consistent.\n  function restoreNodeRangeSelection({ nodeCount, depth, anchorPos }: ActiveDragRange) {\n    const nodeRangeSelection = createDroppedNodeRangeSelection(\n      editor.state.doc,\n      anchorPos,\n      nodeCount,\n      depth,\n    )\n\n    if (nodeRangeSelection) {\n      editor.view.dispatch(editor.state.tr.setSelection(nodeRangeSelection))\n    }\n  }\n\n  function onDrop(e: DragEvent) {\n    if (!e.target || !editor.view.dom.contains(e.target as HTMLElement)) {\n      return\n    }\n\n    // Firefox has a bug where the caret becomes invisible after drag and drop.\n    // This workaround forces Firefox to re-render the caret by toggling contentEditable.\n    // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1327834\n    if (isFirefox()) {\n      const editorElement = editor.view.dom\n\n      // Use requestAnimationFrame to ensure the drop operation has completed\n      requestAnimationFrame(() => {\n        if (editorElement.isContentEditable) {\n          editorElement.contentEditable = 'false'\n          editorElement.contentEditable = 'true'\n        }\n      })\n    }\n\n    if (!activeDragRange || editor.view.state.selection.empty) {\n      return\n    }\n\n    pendingRestore = {\n      ...activeDragRange,\n      anchorPos: editor.state.selection.from,\n    }\n\n    restoreRafId = requestAnimationFrame(() => {\n      restoreRafId = null\n      if (pendingRestore) {\n        restoreNodeRangeSelection(pendingRestore)\n        pendingRestore = null\n      }\n    })\n  }\n\n  // shared teardown for both the unbind() handle and the plugin view destroy\n  function cleanup() {\n    element.removeEventListener('dragstart', onDragStart)\n    element.removeEventListener('dragend', onDragEnd)\n    document.removeEventListener('drop', onDrop)\n\n    if (rafId) {\n      cancelAnimationFrame(rafId)\n      rafId = null\n      pendingMouseCoords = null\n    }\n\n    if (restoreRafId) {\n      cancelAnimationFrame(restoreRafId)\n      restoreRafId = null\n    }\n  }\n\n  wrapper.appendChild(element)\n\n  return {\n    unbind() {\n      cleanup()\n    },\n    plugin: new Plugin({\n      key: typeof pluginKey === 'string' ? new PluginKey(pluginKey) : pluginKey,\n\n      state: {\n        init() {\n          return { locked: false }\n        },\n        apply(tr: Transaction, value: PluginState, _oldState: EditorState, state: EditorState) {\n          if (pendingRestore && tr.docChanged) {\n            const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1)\n\n            if (mappedResult.deleted) {\n              pendingRestore = null\n            } else {\n              pendingRestore.anchorPos = mappedResult.pos\n            }\n          }\n\n          const isLocked = tr.getMeta('lockDragHandle')\n          const hideDragHandle = tr.getMeta('hideDragHandle')\n\n          if (isLocked !== undefined) {\n            locked = isLocked\n          }\n\n          if (hideDragHandle) {\n            hideHandle()\n\n            locked = false\n            currentNode = null\n            currentNodePos = -1\n\n            onNodeChange?.({ editor, node: null, pos: -1 })\n\n            return value\n          }\n\n          // Something has changed and drag handler is visible…\n          if (tr.docChanged && currentNodePos !== -1 && element) {\n            // Yjs replaces the entire document on every incoming change and needs a special handling.\n            // If change comes from another user …\n            if (isChangeOrigin(tr)) {\n              // https://discuss.yjs.dev/t/y-prosemirror-mapping-a-single-relative-position-when-doc-changes/851/3\n              const newPos = getAbsolutePos(state, currentNodeRelPos)\n\n              if (newPos !== currentNodePos) {\n                // Set the new position for our current node.\n                currentNodePos = newPos\n\n                // We will get the outer node with data and position in views update method.\n              }\n            } else {\n              // … otherwise use ProseMirror mapping to update the position.\n              const newPos = tr.mapping.map(currentNodePos)\n\n              if (newPos !== currentNodePos) {\n                // TODO: Remove\n                // console.log('Position has changed …', { old: currentNodePos, new: newPos }, tr);\n\n                // Set the new position for our current node.\n                currentNodePos = newPos\n\n                // Memorize relative position to retrieve absolute position in case of collaboration\n                currentNodeRelPos = getRelativePos(state, currentNodePos)\n\n                // We will get the outer node with data and position in views update method.\n              }\n            }\n          }\n\n          return value\n        },\n      },\n\n      view: view => {\n        element.draggable = true\n        element.style.pointerEvents = 'auto'\n        element.dataset.dragging = 'false'\n\n        editor.view.dom.parentElement?.appendChild(wrapper)\n\n        wrapper.style.pointerEvents = 'none'\n        wrapper.style.position = 'absolute'\n        wrapper.style.top = '0'\n        wrapper.style.left = '0'\n\n        element.addEventListener('dragstart', onDragStart)\n        element.addEventListener('dragend', onDragEnd)\n        document.addEventListener('drop', onDrop)\n\n        return {\n          update(_, oldState) {\n            if (!element) {\n              return\n            }\n\n            if (!editor.isEditable) {\n              hideHandle()\n              return\n            }\n\n            // Prevent element being draggend while being open.\n            if (locked) {\n              element.draggable = false\n            } else {\n              element.draggable = true\n            }\n\n            // Recalculate popup position if doc has changend and drag handler is visible.\n            if (view.state.doc.eq(oldState.doc) || currentNodePos === -1) {\n              return\n            }\n\n            // Get domNode from (new) position.\n            let domNode = view.nodeDOM(currentNodePos) as HTMLElement\n\n            // Since old element could have been wrapped, we need to find\n            // the outer node and take its position and node data.\n            domNode = getOuterDomNode(view, domNode)\n\n            // Skip if domNode is editor dom.\n            if (domNode === view.dom) {\n              return\n            }\n\n            // We only want `Element`.\n            if (domNode?.nodeType !== 1) {\n              return\n            }\n\n            const domNodePos = view.posAtDOM(domNode, 0)\n            const outerNode = getOuterNode(editor.state.doc, domNodePos)\n            const outerNodePos = getOuterNodePos(editor.state.doc, domNodePos) // TODO: needed?\n\n            currentNode = outerNode\n            currentNodePos = outerNodePos\n\n            // Memorize relative position to retrieve absolute position in case of collaboration\n            currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n            onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n            repositionDragHandle(domNode as Element)\n          },\n\n          // TODO: Kills even on hot reload\n          destroy() {\n            cleanup()\n\n            if (element) {\n              removeNode(wrapper)\n            }\n          },\n        }\n      },\n\n      props: {\n        handleDOMEvents: {\n          keydown(view) {\n            if (!element || locked) {\n              return false\n            }\n\n            if (view.hasFocus()) {\n              hideHandle()\n              currentNode = null\n              currentNodePos = -1\n              onNodeChange?.({ editor, node: null, pos: -1 })\n\n              // We want to still continue with other keydown events.\n              return false\n            }\n\n            return false\n          },\n          mouseleave(_view, e) {\n            // Do not hide open popup on mouseleave.\n            if (locked) {\n              return false\n            }\n\n            // If e.target is not inside the wrapper, hide.\n            if (e.target && !wrapper.contains(e.relatedTarget as HTMLElement)) {\n              hideHandle()\n\n              currentNode = null\n              currentNodePos = -1\n\n              onNodeChange?.({ editor, node: null, pos: -1 })\n            }\n\n            return false\n          },\n\n          mousemove(view, e) {\n            // Do not continue if popup is not initialized or open.\n            if (!element || locked) {\n              return false\n            }\n\n            // Store latest mouse coords and schedule a single RAF per frame\n            pendingMouseCoords = { x: e.clientX, y: e.clientY }\n\n            if (rafId) {\n              return false\n            }\n\n            rafId = requestAnimationFrame(() => {\n              rafId = null\n\n              if (!pendingMouseCoords) {\n                return\n              }\n\n              const { x, y } = pendingMouseCoords\n              pendingMouseCoords = null\n\n              const nodeData = findElementNextToCoords({\n                x,\n                y,\n                direction: 'right',\n                editor,\n                nestedOptions,\n              })\n\n              // Skip if there is no node next to coords\n              if (!nodeData.resultElement) {\n                return\n              }\n\n              let domNode = nodeData.resultElement as HTMLElement\n              let targetNode = nodeData.resultNode\n              let targetPos = nodeData.pos\n\n              // In nested mode, the node data already contains the correct target\n              // In non-nested mode, traverse to the top-level block\n              if (!nestedOptions?.enabled) {\n                domNode = getOuterDomNode(view, domNode)\n\n                // Skip if domNode is editor dom.\n                if (domNode === view.dom) {\n                  return\n                }\n\n                // We only want `Element`.\n                if (domNode?.nodeType !== 1) {\n                  return\n                }\n\n                const domNodePos = view.posAtDOM(domNode, 0)\n\n                targetNode = getOuterNode(editor.state.doc, domNodePos)\n                targetPos = getOuterNodePos(editor.state.doc, domNodePos)\n              }\n\n              if (targetNode !== currentNode) {\n                currentNode = targetNode\n                currentNodePos = targetPos ?? -1\n\n                // Memorize relative position to retrieve absolute position in case of collaboration\n                currentNodeRelPos = getRelativePos(view.state, currentNodePos)\n\n                onNodeChange?.({ editor, node: currentNode, pos: currentNodePos })\n\n                // Set nodes clientRect.\n                repositionDragHandle(domNode as Element)\n\n                showHandle()\n              }\n            })\n\n            return false\n          },\n        },\n      },\n    }),\n  }\n}\n","import type { Editor } from '@tiptap/core'\nimport { getSelectionRanges, NodeRangeSelection } from '@tiptap/extension-node-range'\nimport type { Node } from '@tiptap/pm/model'\nimport { type SelectionRange, NodeSelection } from '@tiptap/pm/state'\n\nimport type { NormalizedNestedOptions } from '../types/options.js'\nimport { cloneElement } from './cloneElement.js'\nimport { findElementNextToCoords } from './findNextElementFromCursor.js'\nimport { getDraggedBlockDir, getDraggedBlockElement } from './getDraggedBlockDir.js'\nimport { removeNode } from './removeNode.js'\n\nexport interface DragContext {\n  node: Node | null\n  pos: number\n}\n\nexport function getDragImageOffset(direction: string, wrapperWidth: number): number {\n  return direction === 'rtl' ? wrapperWidth : 0\n}\n\n// The drag preview clone resets its margin so it sits flush against the wrapper\n// origin. Skip the reset when the user explicitly copies a margin property via\n// `dragImageProperties`, otherwise we would discard the value they asked for.\nexport function shouldResetMargin(dragImageProperties?: string[]): boolean {\n  if (!dragImageProperties) {\n    return true\n  }\n\n  return !dragImageProperties.some(property => {\n    const p = property.trim().toLowerCase()\n    return p === 'margin' || p.startsWith('margin-')\n  })\n}\n\nfunction getDragHandleRanges(\n  event: DragEvent,\n  editor: Editor,\n  nestedOptions?: NormalizedNestedOptions,\n  dragContext?: DragContext,\n): SelectionRange[] {\n  const { doc } = editor.view.state\n\n  // In nested mode with known context, use the pre-calculated position\n  // This prevents recalculation issues when mouse position shifts during drag start\n  if (nestedOptions?.enabled && dragContext?.node && dragContext.pos >= 0) {\n    const nodeStart = dragContext.pos\n    const nodeEnd = dragContext.pos + dragContext.node.nodeSize\n\n    return [\n      {\n        $from: doc.resolve(nodeStart),\n        $to: doc.resolve(nodeEnd),\n      },\n    ]\n  }\n\n  // Fallback: recalculate from mouse position (used in non-nested mode)\n  const result = findElementNextToCoords({\n    editor,\n    x: event.clientX,\n    y: event.clientY,\n    direction: 'right',\n    nestedOptions,\n  })\n\n  if (!result.resultNode || result.pos === null) {\n    return []\n  }\n\n  // For non-nested mode, use depth 0 to select the outermost block\n  // Atom nodes (e.g. images) have nodeSize=1 with no opening/closing tokens,\n  // so we must not subtract 1 or we'll create an empty range.\n  const offset = result.resultNode.isText || result.resultNode.isAtom ? 0 : -1\n  const $from = doc.resolve(result.pos)\n  const $to = doc.resolve(result.pos + result.resultNode.nodeSize + offset)\n\n  return getSelectionRanges($from, $to, 0, { extendOnBoundaryOverlap: false })\n}\n\nexport function dragHandler(\n  event: DragEvent,\n  editor: Editor,\n  nestedOptions?: NormalizedNestedOptions,\n  dragContext?: DragContext,\n  dragImageProperties?: string[],\n) {\n  const { view } = editor\n\n  if (!event.dataTransfer) {\n    return\n  }\n\n  const { empty, $from, $to } = view.state.selection\n\n  const dragHandleRanges = getDragHandleRanges(event, editor, nestedOptions, dragContext)\n\n  const selectionRanges = getSelectionRanges($from, $to, 0, { extendOnBoundaryOverlap: false })\n  const isDragHandleWithinSelection = selectionRanges.some(range => {\n    return dragHandleRanges.find(dragHandleRange => {\n      return dragHandleRange.$from === range.$from && dragHandleRange.$to === range.$to\n    })\n  })\n\n  const ranges = empty || !isDragHandleWithinSelection ? dragHandleRanges : selectionRanges\n\n  if (!ranges.length) {\n    return\n  }\n\n  const { tr } = view.state\n  const wrapper = document.createElement('div')\n\n  const from = ranges[0].$from.pos\n  const to = ranges[ranges.length - 1].$to.pos\n  const direction = getDraggedBlockDir(view, from)\n\n  wrapper.setAttribute('dir', direction)\n\n  // For nested mode, create slice directly to avoid NodeRangeSelection expanding to parent\n  const isNestedDrag = nestedOptions?.enabled && dragContext?.node\n  const isSingleBlock = ranges.length === 1\n\n  let slice\n  let selection\n\n  if (isNestedDrag && isSingleBlock) {\n    // Create slice directly from the exact positions\n    slice = view.state.doc.slice(from, to)\n\n    // Use NodeSelection for nested mode to select exactly the target node\n    // NodeRangeSelection would expand to the parent\n    selection = NodeSelection.create(view.state.doc, from)\n  } else {\n    selection = NodeRangeSelection.create(view.state.doc, from, to)\n    slice = selection.content()\n  }\n\n  const resetMargin = shouldResetMargin(dragImageProperties)\n\n  ranges.forEach(range => {\n    const element = getDraggedBlockElement(view, range.$from.pos) as HTMLElement | null\n\n    if (!element) {\n      return\n    }\n\n    const clonedElement = cloneElement(element, dragImageProperties)\n\n    if (resetMargin) {\n      clonedElement.style.margin = '0'\n    }\n\n    wrapper.append(clonedElement)\n  })\n\n  wrapper.style.position = 'absolute'\n  wrapper.style.top = '-10000px'\n  document.body.append(wrapper)\n\n  event.dataTransfer.clearData()\n  const wrapperRect = wrapper.getBoundingClientRect()\n  const dragImageX = getDragImageOffset(direction, wrapperRect.width)\n\n  event.dataTransfer.setDragImage(wrapper, dragImageX, 0)\n\n  let cleanedUp = false\n\n  const cleanupDragPreview = () => {\n    if (cleanedUp) {\n      return\n    }\n\n    cleanedUp = true\n    removeNode(wrapper)\n    document.removeEventListener('drop', cleanupDragPreview)\n    document.removeEventListener('dragend', cleanupDragPreview)\n  }\n\n  // Tell ProseMirror the dragged content.\n  // Pass the NodeSelection as `node` so ProseMirror's drop handler can use it\n  // to precisely delete the original node via `node.replace(tr)`. Without this,\n  // ProseMirror falls back to `tr.deleteSelection()` which relies on the current\n  // selection — but the browser may change the selection during drag, causing the\n  // original node to not be deleted on drop.\n  const nodeSelection = selection instanceof NodeSelection ? selection : undefined\n\n  // The `node` property is used at runtime by ProseMirror's drop handler but is\n  // not exposed in the public type declaration for `view.dragging`.\n  view.dragging = { slice, move: true, node: nodeSelection } as typeof view.dragging\n\n  tr.setSelection(selection)\n\n  view.dispatch(tr)\n\n  // Clean up the drag preview whether the drag results in a valid drop or not.\n  document.addEventListener('drop', cleanupDragPreview)\n  document.addEventListener('dragend', cleanupDragPreview)\n}\n","function getCSSText(element: Element, properties?: string[]) {\n  const style = getComputedStyle(element)\n\n  if (properties) {\n    return properties\n      .map(property => property.trim())\n      .filter(property => property.length > 0)\n      .map(property => `${property}:${style.getPropertyValue(property)};`)\n      .join('')\n  }\n\n  let value = ''\n\n  for (let i = 0; i < style.length; i += 1) {\n    value += `${style[i]}:${style.getPropertyValue(style[i])};`\n  }\n\n  return value\n}\n\nexport function cloneElement(node: HTMLElement, properties?: string[]) {\n  const clonedNode = node.cloneNode(true) as HTMLElement\n  const sourceElements = [node, ...Array.from(node.getElementsByTagName('*'))] as HTMLElement[]\n  const targetElements = [\n    clonedNode,\n    ...Array.from(clonedNode.getElementsByTagName('*')),\n  ] as HTMLElement[]\n\n  sourceElements.forEach((sourceElement, index) => {\n    targetElements[index].style.cssText = getCSSText(sourceElement, properties)\n  })\n\n  return clonedNode\n}\n","import type { DragHandleRule } from '../types/rules.js'\n\n/**\n * The first child inside a list item is the list item's content.\n * It cannot be dragged separately - you drag the list item instead.\n *\n * Example: In `<li><p>Text</p></li>`, the paragraph is excluded,\n * but the listItem is draggable.\n */\nexport const listItemFirstChild: DragHandleRule = {\n  id: 'listItemFirstChild',\n  evaluate: ({ parent, isFirst }) => {\n    if (!isFirst) {\n      return 0\n    }\n\n    const listItemTypes = ['listItem', 'taskItem']\n\n    if (parent && listItemTypes.includes(parent.type.name)) {\n      return 1000\n    }\n\n    return 0\n  },\n}\n\n/**\n * Nodes that contain list items (listItem/taskItem) as direct children\n * are deprioritized. This makes it easier to target individual list items\n * rather than the entire list wrapper.\n *\n * This rule detects list wrappers dynamically by checking if the first child\n * is a list item, rather than hardcoding wrapper type names.\n *\n * Users can still target the list wrapper by moving to the very edge\n * where edge detection kicks in.\n */\nexport const listWrapperDeprioritize: DragHandleRule = {\n  id: 'listWrapperDeprioritize',\n  evaluate: ({ node }) => {\n    const listItemTypes = ['listItem', 'taskItem']\n\n    const firstChild = node.firstChild\n\n    if (firstChild && listItemTypes.includes(firstChild.type.name)) {\n      return 1000\n    }\n\n    return 0\n  },\n}\n\n/**\n * Table rows, cells, and content inside table headers should never be drag targets.\n * Table dragging is handled by table extensions. Only the table wrapper\n * itself or content inside regular table cells should be draggable.\n */\nexport const tableStructure: DragHandleRule = {\n  id: 'tableStructure',\n  evaluate: ({ node, parent }) => {\n    const tableStructureTypes = ['tableRow', 'tableCell', 'tableHeader']\n\n    if (tableStructureTypes.includes(node.type.name)) {\n      return 1000\n    }\n\n    if (parent && parent.type.name === 'tableHeader') {\n      return 1000\n    }\n\n    return 0\n  },\n}\n\n/**\n * Inline nodes (text, marks, inline atoms) should never be drag targets.\n */\nexport const inlineContent: DragHandleRule = {\n  id: 'inlineContent',\n  evaluate: ({ node }) => {\n    if (node.isInline || node.isText) {\n      return 1000\n    }\n\n    return 0\n  },\n}\n\n/**\n * All default rules.\n * Users can extend these or replace them entirely.\n */\nexport const defaultRules: DragHandleRule[] = [\n  listItemFirstChild,\n  listWrapperDeprioritize,\n  tableStructure,\n  inlineContent,\n]\n","import type { EdgeDetectionConfig, EdgeDetectionPreset } from '../types/options.js'\n\n/**\n * Default edge detection configuration.\n */\nconst DEFAULT_EDGE_CONFIG: EdgeDetectionConfig = {\n  edges: ['left', 'top'],\n  threshold: 12,\n  strength: 500,\n}\n\n/**\n * Normalizes edge detection presets or custom config into a full config object.\n * Partial configs are merged with defaults.\n *\n * @param input - The preset string or partial/full config\n * @returns A complete EdgeDetectionConfig\n */\nexport function normalizeEdgeDetection(\n  input: EdgeDetectionPreset | Partial<EdgeDetectionConfig> | undefined,\n): EdgeDetectionConfig {\n  if (input === undefined || input === 'left') {\n    return { ...DEFAULT_EDGE_CONFIG }\n  }\n\n  if (input === 'right') {\n    return { edges: ['right', 'top'], threshold: 12, strength: 500 }\n  }\n\n  if (input === 'both') {\n    return { edges: ['left', 'right', 'top'], threshold: 12, strength: 500 }\n  }\n\n  if (input === 'none') {\n    return { edges: [], threshold: 0, strength: 0 }\n  }\n\n  // Merge partial config with defaults\n  return { ...DEFAULT_EDGE_CONFIG, ...input }\n}\n\n/**\n * Determines if cursor is near specified edges of an element.\n *\n * @param coords - The cursor coordinates\n * @param element - The element to check against\n * @param config - The edge detection configuration\n * @returns True if the cursor is near any of the configured edges\n */\nexport function isNearEdge(\n  coords: { x: number; y: number },\n  element: HTMLElement,\n  config: EdgeDetectionConfig,\n): boolean {\n  if (config.edges.length === 0) {\n    return false\n  }\n\n  const rect = element.getBoundingClientRect()\n  const { threshold, edges } = config\n\n  return edges.some(edge => {\n    if (edge === 'left') {\n      return coords.x - rect.left < threshold\n    }\n\n    if (edge === 'right') {\n      return rect.right - coords.x < threshold\n    }\n\n    if (edge === 'top') {\n      return coords.y - rect.top < threshold\n    }\n\n    if (edge === 'bottom') {\n      return rect.bottom - coords.y < threshold\n    }\n\n    return false\n  })\n}\n\n/**\n * Calculates score deduction for edge proximity.\n * Deeper nodes get larger deductions when near edges,\n * making shallower (parent) nodes win.\n *\n * @param coords - The cursor coordinates\n * @param element - The element to check against (may be null)\n * @param config - The edge detection configuration\n * @param depth - The depth of the node in the document tree\n * @returns The score deduction to apply\n */\nexport function calculateEdgeDeduction(\n  coords: { x: number; y: number },\n  element: HTMLElement | null,\n  config: EdgeDetectionConfig,\n  depth: number,\n): number {\n  if (!element || config.edges.length === 0) {\n    return 0\n  }\n\n  if (isNearEdge(coords, element, config)) {\n    return config.strength * depth\n  }\n\n  return 0\n}\n","import type { EdgeDetectionConfig } from '../types/options.js'\nimport type { DragHandleRule, RuleContext } from '../types/rules.js'\nimport { calculateEdgeDeduction } from './edgeDetection.js'\n\n/**\n * Base score for all nodes. Rules deduct from this score.\n * A node with score <= 0 is excluded from being a drag target.\n */\nexport const BASE_SCORE = 1000\n\n/**\n * Calculates the drag target score for a node.\n * Higher score = more likely to be selected.\n *\n * @param context - The rule context containing node information\n * @param rules - The rules to apply\n * @param edgeConfig - The edge detection configuration\n * @param coords - The cursor coordinates\n * @returns The calculated score, or -1 if the node is excluded\n */\nexport function calculateScore(\n  context: RuleContext,\n  rules: DragHandleRule[],\n  edgeConfig: EdgeDetectionConfig,\n  coords: { x: number; y: number },\n): number {\n  let score = BASE_SCORE\n  let excluded = false\n\n  rules.every(rule => {\n    const deduction = rule.evaluate(context)\n\n    score -= deduction\n\n    if (score <= 0) {\n      excluded = true\n      return false\n    }\n\n    return true\n  })\n\n  if (excluded) {\n    return -1\n  }\n\n  const dom = context.view.nodeDOM(context.pos) as HTMLElement | null\n\n  score -= calculateEdgeDeduction(coords, dom, edgeConfig, context.depth)\n\n  if (score <= 0) {\n    return -1\n  }\n\n  return score\n}\n","import type { Node, ResolvedPos } from '@tiptap/pm/model'\nimport type { EditorView } from '@tiptap/pm/view'\n\nimport type { NormalizedNestedOptions } from '../types/options.js'\nimport type { DragHandleRule, RuleContext } from '../types/rules.js'\nimport { defaultRules } from './defaultRules.js'\nimport { calculateScore } from './scoring.js'\n\n/**\n * Represents a drag target with its node, position, and DOM element.\n */\nexport interface DragTarget {\n  /** The ProseMirror node */\n  node: Node\n\n  /** The absolute position in the document */\n  pos: number\n\n  /** The corresponding DOM element */\n  dom: HTMLElement\n}\n\n/**\n * Checks if any ancestor at or above the given depth is in the allowed list.\n *\n * @param $pos - The resolved position\n * @param depth - The current depth being checked\n * @param allowedTypes - The list of allowed node type names\n * @returns True if any ancestor is in the allowed list\n */\nfunction hasAncestorOfType($pos: ResolvedPos, depth: number, allowedTypes: string[]): boolean {\n  const ancestorDepths = Array.from({ length: depth }, (_, i) => depth - 1 - i)\n\n  return ancestorDepths.some(d => allowedTypes.includes($pos.node(d).type.name))\n}\n\n/**\n * Finds the best drag target at the given coordinates using the scoring system.\n *\n * @param view - The editor view\n * @param coords - The cursor coordinates\n * @param options - The normalized nested options\n * @returns The best drag target, or null if none found\n */\nexport function findBestDragTarget(\n  view: EditorView,\n  coords: { x: number; y: number },\n  options: NormalizedNestedOptions,\n): DragTarget | null {\n  // Validate coordinates are finite numbers to prevent DOM errors\n  if (!Number.isFinite(coords.x) || !Number.isFinite(coords.y)) {\n    return null\n  }\n\n  // ProseMirror expects { left, top } format for coordinates\n  const posInfo = view.posAtCoords({ left: coords.x, top: coords.y })\n\n  if (!posInfo) {\n    return null\n  }\n\n  const { doc } = view.state\n  const $pos = doc.resolve(posInfo.pos)\n\n  const rules: DragHandleRule[] = []\n\n  if (options.defaultRules) {\n    rules.push(...defaultRules)\n  }\n\n  rules.push(...options.rules)\n\n  // Start from depth 1 to exclude the doc node (depth 0) which should never be draggable\n  const depthLevels = Array.from({ length: $pos.depth }, (_, i) => $pos.depth - i)\n\n  const candidates = depthLevels\n    .map(depth => {\n      const node = $pos.node(depth)\n      const nodePos = $pos.before(depth)\n\n      if (options.allowedContainers && depth > 0) {\n        const inAllowedContainer = hasAncestorOfType($pos, depth, options.allowedContainers)\n\n        if (!inAllowedContainer) {\n          return null\n        }\n      }\n\n      const parent = depth > 0 ? $pos.node(depth - 1) : null\n      const index = depth > 0 ? $pos.index(depth - 1) : 0\n      const siblingCount = parent ? parent.childCount : 1\n\n      const context: RuleContext = {\n        node,\n        pos: nodePos,\n        depth,\n        parent,\n        index,\n        isFirst: index === 0,\n        isLast: index === siblingCount - 1,\n        $pos,\n        view,\n      }\n\n      const score = calculateScore(context, rules, options.edgeDetection, coords)\n\n      if (score < 0) {\n        return null\n      }\n\n      const dom = view.nodeDOM(nodePos) as HTMLElement | null\n\n      return { node, pos: nodePos, depth, score, dom }\n    })\n    .filter((candidate): candidate is NonNullable<typeof candidate> => candidate !== null)\n\n  // Atom/leaf nodes (e.g. images) are not ancestors of $pos — they sit at $pos.nodeAfter.\n  // The depth loop above only walks ancestor nodes, so these are missed entirely.\n  // Check for a nodeAfter and evaluate it as an additional candidate.\n  const nodeAfter = $pos.nodeAfter\n\n  if (nodeAfter && nodeAfter.isAtom && !nodeAfter.isInline) {\n    const nodePos = posInfo.pos\n    const depth = $pos.depth + 1\n    const parent = $pos.parent\n    const index = $pos.index()\n    const siblingCount = parent.childCount\n\n    let inAllowedContainer = true\n\n    if (options.allowedContainers) {\n      inAllowedContainer = hasAncestorOfType($pos, depth, options.allowedContainers)\n    }\n\n    if (inAllowedContainer) {\n      const context: RuleContext = {\n        node: nodeAfter,\n        pos: nodePos,\n        depth,\n        parent,\n        index,\n        isFirst: index === 0,\n        isLast: index === siblingCount - 1,\n        $pos,\n        view,\n      }\n\n      const score = calculateScore(context, rules, options.edgeDetection, coords)\n\n      if (score >= 0) {\n        const dom = view.nodeDOM(nodePos) as HTMLElement | null\n\n        if (dom) {\n          candidates.push({ node: nodeAfter, pos: nodePos, depth, score, dom })\n        }\n      }\n    }\n  }\n\n  if (candidates.length === 0) {\n    return null\n  }\n\n  candidates.sort((a, b) => {\n    if (b.score !== a.score) {\n      return b.score - a.score\n    }\n\n    return b.depth - a.depth\n  })\n\n  const winner = candidates[0]\n\n  if (!winner.dom) {\n    return null\n  }\n\n  return {\n    node: winner.node,\n    pos: winner.pos,\n    dom: winner.dom,\n  }\n}\n","import type { Editor } from '@tiptap/core'\nimport type { Node } from '@tiptap/pm/model'\nimport type { EditorView } from '@tiptap/pm/view'\n\nimport type { NormalizedNestedOptions } from '../types/options.js'\nimport { findBestDragTarget } from './findBestDragTarget.js'\n\nexport type FindElementNextToCoords = {\n  x: number\n  y: number\n  direction?: 'left' | 'right'\n  editor: Editor\n  nestedOptions?: NormalizedNestedOptions\n}\n\n/**\n * Finds the draggable block element that is a direct child of view.dom\n */\nexport function findClosestTopLevelBlock(\n  element: Element,\n  view: EditorView,\n): HTMLElement | undefined {\n  let current: Element | null = element\n\n  while (current?.parentElement && current.parentElement !== view.dom) {\n    current = current.parentElement\n  }\n\n  return current?.parentElement === view.dom ? (current as HTMLElement) : undefined\n}\n\n/**\n * Checks if a DOMRect has valid, finite dimensions.\n */\nfunction isValidRect(rect: DOMRect): boolean {\n  return (\n    Number.isFinite(rect.top) &&\n    Number.isFinite(rect.bottom) &&\n    Number.isFinite(rect.left) &&\n    Number.isFinite(rect.right) &&\n    rect.width > 0 &&\n    rect.height > 0\n  )\n}\n\n/**\n * Clamps coordinates to content bounds with O(1) layout reads\n */\nfunction clampToContent(\n  view: EditorView,\n  x: number,\n  y: number,\n  inset = 5,\n): { x: number; y: number } | null {\n  // Validate input coordinates are finite numbers\n  if (!Number.isFinite(x) || !Number.isFinite(y)) {\n    return null\n  }\n\n  const container = view.dom\n  const firstBlock = container.firstElementChild\n  const lastBlock = container.lastElementChild\n\n  if (!firstBlock || !lastBlock) {\n    return null\n  }\n\n  // Clamp Y between first and last block\n  const topRect = firstBlock.getBoundingClientRect()\n  const botRect = lastBlock.getBoundingClientRect()\n\n  // Validate bounding rects have finite values\n  if (!isValidRect(topRect) || !isValidRect(botRect)) {\n    return null\n  }\n\n  const clampedY = Math.min(Math.max(topRect.top + inset, y), botRect.bottom - inset)\n\n  const epsilon = 0.5\n  const sameLeft = Math.abs(topRect.left - botRect.left) < epsilon\n  const sameRight = Math.abs(topRect.right - botRect.right) < epsilon\n\n  let rowRect: DOMRect = topRect\n\n  if (sameLeft && sameRight) {\n    // Most of the time, every block has the same width\n    rowRect = topRect\n  } else {\n    // TODO\n    // find the actual block at the clamped Y\n    // This case is rare, avoid for now\n  }\n\n  // Clamp X to the chosen block's bounds\n  const clampedX = Math.min(Math.max(rowRect.left + inset, x), rowRect.right - inset)\n\n  // Final validation of output coordinates\n  if (!Number.isFinite(clampedX) || !Number.isFinite(clampedY)) {\n    return null\n  }\n\n  return { x: clampedX, y: clampedY }\n}\n\nexport const findElementNextToCoords = (\n  options: FindElementNextToCoords,\n): {\n  resultElement: HTMLElement | null\n  resultNode: Node | null\n  pos: number | null\n} => {\n  const { x, y, editor, nestedOptions } = options\n  const { view, state } = editor\n\n  const clamped = clampToContent(view, x, y, 5)\n\n  // Return early if coordinates could not be clamped to valid bounds\n  if (!clamped) {\n    return { resultElement: null, resultNode: null, pos: null }\n  }\n\n  const { x: clampedX, y: clampedY } = clamped\n\n  // When nested mode is enabled, use the scoring-based detection\n  if (nestedOptions?.enabled) {\n    const target = findBestDragTarget(view, { x: clampedX, y: clampedY }, nestedOptions)\n\n    if (!target) {\n      return { resultElement: null, resultNode: null, pos: null }\n    }\n\n    return {\n      resultElement: target.dom,\n      resultNode: target.node,\n      pos: target.pos,\n    }\n  }\n\n  // Original root-level detection for non-nested mode\n  const elements = view.root.elementsFromPoint(clampedX, clampedY)\n\n  let block: HTMLElement | undefined\n\n  Array.prototype.some.call(elements, (el: Element) => {\n    if (!view.dom.contains(el)) {\n      return false\n    }\n    const candidate = findClosestTopLevelBlock(el, view)\n    if (candidate) {\n      block = candidate\n      return true\n    }\n    return false\n  })\n\n  if (!block) {\n    // elementsFromPoint may return nothing if the coordinates land outside an element\n    // (e.g., in margins, overlays, gaps, or indented nodes). posAtCoords uses the\n    // caret API, so it still resolves to the nearest text position.\n    const coords = view.posAtCoords({ left: clampedX, top: clampedY })\n\n    if (coords) {\n      const $pos = state.doc.resolve(coords.pos)\n      // Walk up to the top-level block\n      const depth = Math.min($pos.depth, 1)\n      const blockPos = depth > 0 ? $pos.before(depth) : $pos.pos\n      const blockNode = state.doc.nodeAt(blockPos)\n\n      if (blockNode) {\n        const dom = view.nodeDOM(blockPos)\n\n        return {\n          resultElement: dom instanceof HTMLElement ? dom : null,\n          resultNode: blockNode,\n          pos: blockPos,\n        }\n      }\n    }\n\n    return { resultElement: null, resultNode: null, pos: null }\n  }\n\n  let pos: number\n  try {\n    pos = view.posAtDOM(block, 0)\n  } catch {\n    return { resultElement: null, resultNode: null, pos: null }\n  }\n\n  const node = state.doc.nodeAt(pos)\n\n  if (!node) {\n    // This case occurs when an atom node is allowed to contain inline content.\n    // We need to resolve the position here to ensure we target the correct parent node.\n    const resolvedPos = state.doc.resolve(pos)\n    const parent = resolvedPos.parent\n\n    return {\n      resultElement: block,\n      resultNode: parent,\n      pos: resolvedPos.start(),\n    }\n  }\n\n  return {\n    resultElement: block,\n    resultNode: node,\n    pos,\n  }\n}\n","import type { EditorView } from '@tiptap/pm/view'\n\n/**\n * Resolves the DOM element that visually represents the dragged block.\n */\nexport function getDraggedBlockElement(view: EditorView, pos: number): Element | null {\n  const nodeDom = view.nodeDOM(pos)\n\n  if (nodeDom instanceof Element && nodeDom !== view.dom) {\n    return nodeDom\n  }\n\n  const { node, offset } = view.domAtPos(pos)\n  const child = node.childNodes[offset]\n\n  if (child instanceof Element) {\n    return child\n  }\n\n  if (node instanceof Element) {\n    return node\n  }\n\n  if (node.nodeType === Node.TEXT_NODE && node.parentElement) {\n    return node.parentElement\n  }\n\n  return null\n}\n\n/**\n * Resolves the text direction (`dir` attribute value) for the block being\n * dragged. Uses `view.nodeDOM` first because it maps a ProseMirror position\n * directly to the block-level DOM element. Falls back to `view.domAtPos` with\n * proper child-at-offset resolution when `nodeDOM` doesn't return an element,\n * and ultimately to the editor root direction.\n */\nexport function getDraggedBlockDir(view: EditorView, pos: number): string {\n  const draggedDom = getDraggedBlockElement(view, pos)\n\n  const contentDir = draggedDom\n    ? getComputedStyle(draggedDom).direction\n    : getComputedStyle(view.dom).direction\n\n  return contentDir || 'ltr'\n}\n","export function removeNode(node: HTMLElement) {\n  node.parentNode?.removeChild(node)\n}\n","import { isNodeRangeSelection, NodeRangeSelection } from '@tiptap/extension-node-range'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { Selection } from '@tiptap/pm/state'\n\nexport interface ActiveDragRange {\n  anchorPos: number\n  nodeCount: number\n  depth: number\n}\n\ninterface DroppedBlockRange {\n  anchor: number\n  head: number\n  count: number\n}\n\nfunction sumNodeSizes(parent: ProseMirrorNode, from: number, to: number): number {\n  let size = 0\n\n  for (let i = from; i < to; i += 1) {\n    size += parent.child(i).nodeSize\n  }\n\n  return size\n}\n\n// Captures a multi-block node range at dragstart so it can be restored after drop.\nexport function getActiveDragRange(selection: Selection): ActiveDragRange | null {\n  if (!isNodeRangeSelection(selection)) {\n    return null\n  }\n\n  return {\n    anchorPos: selection.from,\n    nodeCount: selection.ranges.length,\n    depth: selection.depth ?? 0,\n  }\n}\n\n/**\n * Computes the position range of the freshly dropped blocks so a\n * `NodeRangeSelection` can be restored over them after a drag-and-drop.\n */\nfunction getDroppedBlockRange(\n  doc: ProseMirrorNode,\n  anchorPos: number,\n  nodeCount: number,\n  depth: number,\n): DroppedBlockRange | null {\n  const $pos = doc.resolve(anchorPos)\n  const parent = $pos.node(depth)\n  let index = $pos.index(depth)\n\n  // the drop can land past the last child, so clamp the index back into range\n  if (index >= parent.childCount) {\n    index = Math.max(0, parent.childCount - nodeCount)\n  }\n\n  const count = Math.min(nodeCount, parent.childCount - index)\n\n  if (count <= 0) {\n    return null\n  }\n\n  const blockStart = $pos.start(depth) + sumNodeSizes(parent, 0, index)\n  const blockEnd = blockStart + sumNodeSizes(parent, index, index + count)\n\n  return { anchor: blockStart, head: blockEnd, count }\n}\n\n// Rebuilds the dragged node range over the dropped blocks, or null when unsafe.\nexport function createDroppedNodeRangeSelection(\n  doc: ProseMirrorNode,\n  anchorPos: number,\n  nodeCount: number,\n  depth: number,\n): NodeRangeSelection | null {\n  try {\n    const range = getDroppedBlockRange(doc, anchorPos, nodeCount, depth)\n\n    if (!range) {\n      return null\n    }\n\n    const selection = NodeRangeSelection.create(doc, range.anchor, range.head, depth)\n\n    return selection.ranges.length === nodeCount ? selection : null\n  } catch {\n    return null\n  }\n}\n","import type { Node } from '@tiptap/pm/model'\n\nexport const getOuterNodePos = (doc: Node, pos: number): number => {\n  const resolvedPos = doc.resolve(pos)\n  const { depth } = resolvedPos\n\n  if (depth === 0) {\n    return pos\n  }\n\n  const a = resolvedPos.pos - resolvedPos.parentOffset\n\n  return a - 1\n}\n\nexport const getOuterNode = (doc: Node, pos: number): Node | null => {\n  const node = doc.nodeAt(pos)\n  const resolvedPos = doc.resolve(pos)\n\n  let { depth } = resolvedPos\n  let parent = node\n\n  while (depth > 0) {\n    const currentNode = resolvedPos.node(depth)\n\n    depth -= 1\n\n    if (depth === 0) {\n      parent = currentNode\n    }\n  }\n\n  return parent\n}\n","import type { NestedOptions, NormalizedNestedOptions } from '../types/options.js'\nimport { normalizeEdgeDetection } from './edgeDetection.js'\n\n/**\n * Normalizes the nested options input into a complete configuration object.\n *\n * @param input - The nested option (boolean, object, or undefined)\n * @returns A fully normalized options object\n *\n * @example\n * // Simple enable\n * normalizeNestedOptions(true)\n * // Returns: { enabled: true, rules: [], defaultRules: true, ... }\n *\n * @example\n * // Custom config\n * normalizeNestedOptions({ rules: [myRule], edgeDetection: 'none' })\n * // Returns: { enabled: true, rules: [myRule], edgeDetection: { edges: [], ... } }\n */\nexport function normalizeNestedOptions(\n  input: boolean | NestedOptions | undefined,\n): NormalizedNestedOptions {\n  if (input === false || input === undefined) {\n    return {\n      enabled: false,\n      rules: [],\n      defaultRules: true,\n      allowedContainers: undefined,\n      edgeDetection: normalizeEdgeDetection('none'),\n    }\n  }\n\n  if (input === true) {\n    return {\n      enabled: true,\n      rules: [],\n      defaultRules: true,\n      allowedContainers: undefined,\n      edgeDetection: normalizeEdgeDetection('left'),\n    }\n  }\n\n  return {\n    enabled: true,\n    rules: input.rules ?? [],\n    defaultRules: input.defaultRules ?? true,\n    allowedContainers: input.allowedContainers,\n    edgeDetection: normalizeEdgeDetection(input.edgeDetection),\n  }\n}\n"],"mappings":"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","names":["import_core","import_state","import_extension_node_range"]}