Split Node Operation

Split a node at a specific position into two nodes.

Overview

The split node operation divides a node at a specific position into two separate nodes. Commonly used when user presses Enter to split a paragraph.

Interface

interface SplitNodeOperation extends Operation {
  type: 'splitNode';
  path: Path;
  position: number; // Position within node to split
  depth?: number; // How deep to split (default: 0, split at top level)
}

Usage

// Split paragraph at cursor position
function splitParagraph(editor: Editor, position: Path) {
  const operation: SplitNodeOperation = {
    type: 'splitNode',
    path: position,
    position: position[1] // Offset within paragraph
  };
  
  editor.applyOperation(operation);
}

// Split at specific offset
function splitAtOffset(editor: Editor, nodePath: Path, offset: number) {
  const operation: SplitNodeOperation = {
    type: 'splitNode',
    path: nodePath,
    position: offset
  };
  
  editor.applyOperation(operation);
}

// In transaction (can be decomposed into replace + insert)
function splitInTransaction(editor: Editor, position: Path) {
  const tx = editor.beginTransaction();
  const node = editor.getNodeAtPath(position);
  
  const beforeText = node.text.slice(0, position[1]);
  const afterText = node.text.slice(position[1]);
  
  // Update current node
  tx.add({
    type: 'replace',
    path: position,
    length: node.text.length,
    content: beforeText
  });
  
  // Insert new node
  tx.add({
    type: 'insertNode',
    path: [position[0] + 1],
    node: {
      type: node.type,
      children: [{ type: 'text', text: afterText }]
    }
  });
  
  tx.commit();
}

Inverse Operation

The inverse of split node is merge nodes:

function getInverse(operation: SplitNodeOperation): MergeNodesOperation {
  return {
    type: 'mergeNodes',
    path: operation.path,
    targetPath: [operation.path[0] + 1], // Next sibling
    position: operation.position
  };
}