{"version":3,"file":"mentions.cjs","sources":["../../../src/slate/plugins/mentions.ts"],"sourcesContent":["import type { Node as SlateNode } from \"slate\";\nimport {\n  Editor as SlateEditor,\n  Element as SlateElement,\n  Range as SlateRange,\n  Transforms as SlateTransforms,\n} from \"slate\";\n\nimport type { ComposerBodyMention } from \"../../types\";\nimport { getCharacterAfter, getCharacterBefore } from \"../utils/get-character\";\nimport { getMatchRange } from \"../utils/get-match-range\";\nimport { isEmptyString } from \"../utils/is-empty-string\";\nimport { isWhitespaceCharacter } from \"../utils/is-whitespace-character\";\n\nexport const MENTION_CHARACTER = \"@\";\n\nexport type MentionDraft = {\n  range: SlateRange;\n  text: string;\n};\n\nexport function getMentionDraftAtSelection(\n  editor: SlateEditor\n): MentionDraft | undefined {\n  const { selection } = editor;\n\n  if (!selection || !SlateRange.isCollapsed(selection)) {\n    return;\n  }\n\n  // Walk backwards from the selection until \"@\" is found, unless the character\n  // before isn't whitespace (or \"@\" is the block's first character)\n  const match = getMatchRange(editor, selection, [\"@\"], {\n    include: true,\n    allowConsecutiveWhitespace: false,\n    ignoreTerminator: (_, point) => {\n      const characterBefore = getCharacterBefore(editor, point);\n\n      // Ignore \"@\" if it's preceded by a non-whitespace character\n      if (characterBefore && !isWhitespaceCharacter(characterBefore.text)) {\n        return true;\n      }\n\n      return false;\n    },\n  });\n\n  if (!match) {\n    return;\n  }\n\n  const matchText = SlateEditor.string(editor, match);\n\n  // Check if the match starts with the mention character (not followed by a whitespace character)\n  if (\n    !matchText.startsWith(MENTION_CHARACTER) ||\n    (matchText.length > 1 && isWhitespaceCharacter(matchText[1]))\n  ) {\n    return;\n  }\n\n  return {\n    range: match,\n    // Exclude the mention character from the text\n    text: matchText.substring(1),\n  };\n}\n\nexport function isComposerBodyMention(\n  node: SlateNode\n): node is ComposerBodyMention {\n  return SlateElement.isElement(node) && node.type === \"mention\";\n}\n\nexport function insertMention(editor: SlateEditor, userId: string) {\n  const mention: ComposerBodyMention = {\n    type: \"mention\",\n    id: userId,\n    children: [{ text: \"\" }],\n  };\n\n  // Insert the mention\n  SlateTransforms.insertNodes(editor, mention);\n  SlateTransforms.move(editor);\n\n  const afterCharacter = editor.selection\n    ? getCharacterAfter(editor, editor.selection)\n    : undefined;\n\n  if (!afterCharacter || afterCharacter.void) {\n    // Insert a following space if needed\n    SlateTransforms.insertText(editor, \" \");\n  } else if (isEmptyString(afterCharacter.text)) {\n    // Move the selection if it's already followed by a space\n    SlateTransforms.move(editor);\n  }\n}\n\nexport function insertMentionCharacter(editor: SlateEditor) {\n  if (!editor.selection) {\n    return;\n  }\n\n  // Check if the selection is preceded or followed by a non-whitespace character\n  const beforeCharacter = getCharacterBefore(editor, editor.selection, {\n    filterVoids: true,\n  });\n  const afterCharacter = getCharacterAfter(editor, editor.selection, {\n    filterVoids: true,\n  });\n  const shouldInsertSpaceBefore =\n    beforeCharacter && !isEmptyString(beforeCharacter.text);\n  const shouldInsertSpaceAfter =\n    afterCharacter && !isEmptyString(afterCharacter.text);\n\n  if (!SlateRange.isCollapsed(editor.selection)) {\n    const text =\n      (shouldInsertSpaceBefore ? \" \" : \"\") +\n      MENTION_CHARACTER +\n      (shouldInsertSpaceAfter ? \" \" : \"\");\n\n    // If the selection is collapsed, insert the mention character at the current selection\n    editor.insertText(text);\n\n    // If a following space was inserted, move the selection back by one\n    if (shouldInsertSpaceAfter) {\n      SlateTransforms.move(editor, {\n        distance: 1,\n        unit: \"character\",\n        reverse: true,\n      });\n    }\n  } else {\n    const beforeText = (shouldInsertSpaceBefore ? \" \" : \"\") + MENTION_CHARACTER;\n\n    // If the selection is not collapsed, insert the mention character before the selection\n    editor.insertText(beforeText, { at: SlateRange.start(editor.selection) });\n\n    if (shouldInsertSpaceAfter) {\n      editor.insertText(\" \", { at: SlateRange.end(editor.selection) });\n    }\n\n    // Collapse the selection at its end\n    SlateTransforms.collapse(editor, { edge: \"end\" });\n  }\n}\n\nexport function withMentions<T extends SlateEditor>(editor: T): T {\n  const { isInline, isVoid, markableVoid, deleteBackward } = editor;\n\n  editor.isInline = (element) => {\n    return isComposerBodyMention(element) || isInline(element);\n  };\n\n  editor.isVoid = (element) => {\n    return isComposerBodyMention(element) || isVoid(element);\n  };\n\n  editor.markableVoid = (element) => {\n    return isComposerBodyMention(element) || markableVoid(element);\n  };\n\n  editor.deleteBackward = (unit) => {\n    const { selection } = editor;\n\n    if (selection && SlateRange.isCollapsed(selection)) {\n      const [mention] = SlateEditor.nodes(editor, {\n        at:\n          unit === \"character\"\n            ? SlateEditor.before(editor, selection, { unit: \"character\" })\n            : selection,\n        match: isComposerBodyMention,\n      });\n\n      deleteBackward(unit);\n\n      if (mention) {\n        SlateTransforms.insertText(editor, MENTION_CHARACTER);\n      }\n    } else {\n      deleteBackward(unit);\n    }\n  };\n\n  return editor;\n}\n"],"names":["SlateRange","getMatchRange","getCharacterBefore","isWhitespaceCharacter","SlateEditor","SlateElement","SlateTransforms","getCharacterAfter","isEmptyString"],"mappings":"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"}