{"version":3,"file":"index.cjs","names":["getSelectionRanges","NodeSelection","NodeRangeSelection","isNodeRangeSelection","NodeRangeSelection","ySyncPluginKey","absolutePositionToRelativePosition","relativePositionToAbsolutePosition","PluginKey","isChangeOrigin","isFirefox","Plugin","Extension"],"sources":["../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/dragHandler.ts","../src/helpers/getOuterNode.ts","../src/helpers/nodeRangeDrop.ts","../src/drag-handle-plugin.ts","../src/helpers/normalizeOptions.ts","../src/drag-handle.ts","../src/index.ts"],"sourcesContent":["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 `
  • Text

  • `, 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 | 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 => 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 * ProseMirror attaches a `pmViewDesc` to every DOM node it manages. Element view\n * descriptions for document nodes expose a `node`; widget decorations (such as\n * the Pages page-chrome overlay, which renders as a zero-height first child of\n * the editor) have a view description but no associated document node.\n */\ninterface ElementWithViewDesc extends Element {\n pmViewDesc?: { node?: unknown }\n}\n\n/**\n * Finds the draggable block element that is a direct child of view.dom.\n *\n * Direct children that are widget decorations rather than document content are\n * skipped — they are not draggable blocks, and treating them as such would\n * align the drag handle to the decoration (e.g. the page header) instead of the\n * actual first block on the page.\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 if (current?.parentElement !== view.dom) {\n return undefined\n }\n\n // Skip widget decorations (no associated document node).\n if (!(current as ElementWithViewDesc).pmViewDesc?.node) {\n return undefined\n }\n\n return current as HTMLElement\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 * Returns the bounding rect of the first or last child of `container` that has\n * a valid (non-zero) layout box.\n *\n * Some extensions insert zero-size widget decorations as the first/last child\n * of the editor — for example the Pages extension anchors its page-chrome\n * overlay in a zero-height `
    ` as the first child. Reading `firstElementChild`\n * / `lastElementChild` directly would yield an invalid rect and abort clamping,\n * so we skip over any edge children without a valid box.\n */\nexport function edgeBlockRect(container: Element, edge: 'first' | 'last'): DOMRect | null {\n let current: Element | null =\n edge === 'first' ? container.firstElementChild : container.lastElementChild\n\n while (current) {\n const rect = current.getBoundingClientRect()\n\n if (isValidRect(rect)) {\n return rect\n }\n\n current = edge === 'first' ? current.nextElementSibling : current.previousElementSibling\n }\n\n return null\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\n // Clamp Y between the first and last children that actually have a layout box.\n const topRect = edgeBlockRect(container, 'first')\n const botRect = edgeBlockRect(container, 'last')\n\n if (!topRect || !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 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","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 { isNodeRangeSelection, NodeRangeSelection } from '@tiptap/extension-node-range'\nimport type { Node as ProseMirrorNode } from '@tiptap/pm/model'\nimport type { Selection } from '@tiptap/pm/state'\nimport type { RelativePosition } from '@tiptap/y-tiptap'\nimport type { ActiveDragRange } from '../types/activeDragRange.js'\n\ninterface MapPendingRestoreAnchorOptions {\n isChangeOrigin: boolean\n getAbsolutePos: (relativePos: RelativePosition) => number\n}\n\n// Remaps the drop anchor while a restore is pending. Returns null when the anchor\n// can no longer be resolved.\nexport function mapPendingRestoreAnchor(\n pendingRestore: ActiveDragRange,\n tr: {\n docChanged: boolean\n mapping: { mapResult: (pos: number, bias: number) => { deleted: boolean; pos: number } }\n },\n options: MapPendingRestoreAnchorOptions,\n): ActiveDragRange | null {\n if (!tr.docChanged) {\n return pendingRestore\n }\n\n if (options.isChangeOrigin && pendingRestore.relativeAnchorPos != null) {\n const newPos = options.getAbsolutePos(pendingRestore.relativeAnchorPos)\n\n if (!Number.isFinite(newPos) || newPos <= 0) {\n return null\n }\n\n return {\n ...pendingRestore,\n anchorPos: newPos,\n }\n }\n\n const mappedResult = tr.mapping.mapResult(pendingRestore.anchorPos, 1)\n\n if (mappedResult.deleted) {\n return null\n }\n\n return {\n ...pendingRestore,\n anchorPos: mappedResult.pos,\n }\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 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 } from '@tiptap/pm/state'\nimport type { EditorView } from '@tiptap/pm/view'\nimport {\n absolutePositionToRelativePosition,\n relativePositionToAbsolutePosition,\n ySyncPluginKey,\n} from '@tiptap/y-tiptap'\nimport type { RelativePosition } from '@tiptap/y-tiptap'\n\nimport { dragHandler } from './helpers/dragHandler.js'\nimport { findElementNextToCoords } from './helpers/findNextElementFromCursor.js'\nimport { getOuterNode, getOuterNodePos } from './helpers/getOuterNode.js'\nimport {\n createDroppedNodeRangeSelection,\n getActiveDragRange,\n mapPendingRestoreAnchor,\n} from './helpers/nodeRangeDrop.js'\nimport { removeNode } from './helpers/removeNode.js'\nimport type { NormalizedNestedOptions } from './types/options.js'\nimport type { ActiveDragRange } from './types/activeDragRange.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\nconst getAbsolutePos = (state: EditorState, relativePos: RelativePosition | null) => {\n const ystate = ySyncPluginKey.getState(state)\n\n if (!ystate) {\n return -1\n }\n if (relativePos === null) return 0\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 let currentNodeRelPos: RelativePosition | null = null\n let rafId: 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 clearDragRangeState() {\n activeDragRange = null\n pendingRestore = null\n }\n\n function remapPendingRestore(tr: Transaction, state: EditorState) {\n if (!pendingRestore) {\n return\n }\n\n pendingRestore = mapPendingRestoreAnchor(pendingRestore, tr, {\n isChangeOrigin: isChangeOrigin(tr),\n getAbsolutePos: relativePos => getAbsolutePos(state, relativePos),\n })\n }\n\n function buildRestoreTransaction(state: EditorState) {\n if (!pendingRestore) {\n return null\n }\n\n const nodeRangeSelection = createDroppedNodeRangeSelection(\n state.doc,\n pendingRestore.anchorPos,\n pendingRestore.nodeCount,\n pendingRestore.depth,\n )\n\n if (!nodeRangeSelection) {\n pendingRestore = null\n activeDragRange = null\n return null\n }\n\n clearDragRangeState()\n\n return state.tr.setSelection(nodeRangeSelection)\n }\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 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 const anchorPos = editor.state.selection.from\n const relativeAnchorPos = getRelativePos(editor.state, anchorPos)\n\n pendingRestore = {\n ...activeDragRange,\n anchorPos,\n relativeAnchorPos: relativeAnchorPos ?? undefined,\n }\n\n // Dispatch a no-op transaction so appendTransaction can restore the node\n // range after any Yjs isChangeOrigin transactions from the drop have settled.\n editor.view.dispatch(editor.state.tr.setMeta('addToHistory', false))\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 clearDragRangeState()\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 remapPendingRestore(tr, state)\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 appendTransaction(_transactions, _oldState, newState) {\n return buildRestoreTransaction(newState)\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 // Keep the handle above positioned editor content/decorations (e.g. the\n // Pages page header/footer chrome) so it stays visible and clickable.\n wrapper.style.zIndex = '10'\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 { 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","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 {\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({\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 { 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"],"mappings":"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"}