handleInsertNodeExceution function

void handleInsertNodeExceution(
  1. String nodeType,
  2. FluentDocument document,
  3. Map<String, dynamic> options
)

Inserts a new node at the cursor.

  • If there's a selection: it's removed first.
  • Link (inline): inserted at the cursor, splitting the fragment.
  • Other nodes (block): inserted after the current container.

Implementation

void handleInsertNodeExceution(
  String nodeType,
  FluentDocument document,
  Map<String, dynamic> options,
) {
  final root = document.content;
  final cursor = document.cursor;

  // If there's a selection and we're inserting a list, convert the
  // selected text into list items.
  if (!cursor.isCollapsed && nodeType == 'list') {
    final sel = resolveSelection(
      root,
      cursor.anchorId,
      cursor.anchorOffset,
      cursor.focusId,
      cursor.focusOffset,
      cachedStops: document.caretStops,
      cachedLines: document.logicalLines,
    );
    if (sel != null && sel.nodes.isNotEmpty) {
      final items = <ListItem>[];
      for (final node in sel.nodes) {
        final text = _extractSelectedText(root, node);
        if (text.isNotEmpty && text != Whitespaces.zws) {
          final paragraph = Paragraph(text: text);
          final firstFrag = paragraph.fragments.first as Fragment;
          final sourceFrag = _findFirstFragmentInSelection(root, node);
          if (sourceFrag != null) {
            firstFrag.styles = List<String>.from(sourceFrag.styles ?? []);
            firstFrag.fontFamily = sourceFrag.fontFamily;
            firstFrag.fontSize = sourceFrag.fontSize;
            firstFrag.color = sourceFrag.color;
            firstFrag.highlightColor = sourceFrag.highlightColor;
          }
          final item = ListItem(
            bulletType: options['listType'] as String? ?? 'bullet',
            indexList: [1],
            children: [paragraph],
          );
          items.add(item);
        }
      }
      if (items.isNotEmpty) {
        // Remove the selected text (collapses cursor).
        executeHandleReplaceSelection('', document);
        // Build the list with the extracted text.
        final list = FluentList(
          listType: options['listType'] as String? ?? 'bullet',
        );
        list.items.addAll(items);
        _insertBlockNode(root, document.cursor, list, document);
        return;
      }
    }
  }

  // If there's a selection, remove it and collapse the cursor.
  if (!cursor.isCollapsed) {
    executeHandleReplaceSelection('', document);
  }

  // Create the new node
  final newNode = makeNode(nodeType, options);

  // Link is inline: insert it inside the container at the cursor
  if (newNode is Link) {
    _insertLinkInline(root, cursor, newNode, document);
    return;
  }

  // Image: inline by default, block only when the cursor is
  // at the beginning or end of a root-level Paragraph.
  if (newNode is FluentImage) {
    _insertImage(root, cursor, newNode, document);
    return;
  }

  // Other nodes are block: insert them after the current container
  _insertBlockNode(root, cursor, newNode, document);
}