executeHandleReplaceSelection function

void executeHandleReplaceSelection(
  1. String character,
  2. FluentDocument document
)

Implementation

void executeHandleReplaceSelection(String character, FluentDocument document) {
  if (document.registry.dispatchReplaceSelection(character, document)) return;

  final sel = resolveSelectionFromCursor(document);

  if (sel == null) return;

  final root = document.content;

  final cursorTarget = sel.isSingleNode
      ? _replaceSingleNode(document, sel, character, root)
      : _replaceMultiNode(document, sel, character, root);

  // Tree structure and text changed: invalidate caches now so cursor and
  // selection updates work against the current document state.
  document.invalidateNodeIndex();

  document.cursor.moveTo(
    cursorTarget.fragId,
    cursorTarget.offset,
  );

  // Move the SelectionManager to the same collapsed position as the cursor,
  // discarding the old selection range instead of keeping its stale anchor.
  final newContainerId = document.findLogicalContainerId(cursorTarget.fragId) ??
      (sel.base.container as FNode).id;
  document.selectionManager.startSelection(
    newContainerId,
    cursorTarget.fragId,
    cursorTarget.offset,
  );

  if (sel.isSingleNode && sel.base.fragment.id == sel.extent.fragment.id) {
    final paragraphId = (sel.base.container as FNode).id;
    final globalOffset = document.getGlobalOffsetInParagraph(
      paragraphId,
      sel.base.fragment.id,
      sel.base.offset,
    );
    if (globalOffset != null) {
      final delta = character.length - (sel.extent.offset - sel.base.offset);
      document.notifyTextMutation(paragraphId, globalOffset, delta);
    }
  }

  recalculateListIndicesFor(
    root,
    sel.nodes.map((n) => n.container as FNode).toSet(),
    document: document,
  );

  document.updateContent();
  document.cursorOnlyUpdate();
}