{"version":3,"file":"mention-plugin.cjs","sources":["../../src/mentions/mention-plugin.tsx"],"sourcesContent":["import {\n  autoUpdate,\n  flip,\n  hide,\n  limitShift,\n  offset,\n  shift,\n  size,\n  useFloating,\n} from \"@floating-ui/react-dom\";\nimport { useLexicalComposerContext } from \"@lexical/react/LexicalComposerContext\";\nimport {\n  assertNever,\n  MENTION_CHARACTER,\n  type MentionData,\n} from \"@liveblocks/core\";\nimport { useRoom } from \"@liveblocks/react\";\nimport {\n  useCreateTextMention,\n  useDeleteTextMention,\n  useLayoutEffect,\n  useMentionSuggestions,\n} from \"@liveblocks/react/_private\";\nimport {\n  Group,\n  GroupAvatar,\n  GroupDescription,\n  Portal,\n  User,\n  UserAvatar,\n  UsersIcon,\n} from \"@liveblocks/react-ui/_private\";\nimport type { EditorState, NodeKey, NodeMutation, TextNode } from \"lexical\";\nimport {\n  $createRangeSelection,\n  $createTextNode,\n  $getNodeByKey,\n  $getSelection,\n  $isElementNode,\n  $isNodeSelection,\n  $isRangeSelection,\n  $isTextNode,\n  $setSelection,\n  COMMAND_PRIORITY_LOW,\n  KEY_BACKSPACE_COMMAND,\n} from \"lexical\";\nimport type { ReactNode } from \"react\";\nimport { useCallback, useEffect, useState } from \"react\";\n\nimport {\n  $createGroupMentionNode,\n  $isGroupMentionNode,\n  GroupMentionNode,\n} from \"./group-mention-node\";\nimport {\n  $createMentionNode,\n  $isMentionNode,\n  MentionNode,\n} from \"./mention-node\";\nimport * as Suggestions from \"./suggestions\";\nimport {\n  OnResetMatchCallbackContext,\n  OnSuggestionSelectCallbackContext,\n  SuggestionsContext,\n} from \"./suggestions\";\n\nconst PUNCTUATIONS =\n  \"\\\\.,\\\\+\\\\*\\\\?\\\\$\\\\@\\\\|#{}\\\\(\\\\)\\\\^\\\\-\\\\[\\\\]\\\\\\\\/!%'\\\"~=<>_:;\";\n\n// Characters we expect to see in a mention (non-space, non-punctuation).\nconst VALID_CHARACTERS = \"[^\" + MENTION_CHARACTER + PUNCTUATIONS + \"\\\\s]\";\n\nconst VALID_JOINS =\n  \"(?:\" +\n  \"\\\\.[ |$]|\" + // E.g. \"r. \" in \"Mr. Smith\"\n  \" |\" + // E.g. \" \" in \"Josh Duck\"\n  \"[\" +\n  PUNCTUATIONS +\n  \"]|\" + // E.g. \"-' in \"Salier-Hellendag\"\n  \")\";\n\nconst LENGTH_LIMIT = 75;\n\nconst MentionRegex = new RegExp(\n  \"(^|\\\\s|\\\\()(\" +\n    \"[\" +\n    MENTION_CHARACTER +\n    \"]\" +\n    \"((?:\" +\n    VALID_CHARACTERS +\n    VALID_JOINS +\n    \"){0,\" +\n    LENGTH_LIMIT +\n    \"})\" +\n    \")$\"\n);\n\nfunction $getAnchorNodeTextContent(): string | null {\n  const selection = $getSelection();\n  if (!$isRangeSelection(selection)) return null;\n\n  const anchor = selection.anchor;\n  if (anchor.type !== \"text\") return null;\n  const anchorNode = anchor.getNode();\n  if (!anchorNode.isSimpleText()) return null;\n  const anchorOffset = anchor.offset;\n  return anchorNode.getTextContent().slice(0, anchorOffset);\n}\n\n/**\n * Walk backwards along user input and forward through entity title to try and replace more of the user's text with entity.\n */\nfunction getFullMatchOffset(\n  documentText: string,\n  entryText: string,\n  offset: number\n): number {\n  let triggerOffset = offset;\n  for (let i = triggerOffset; i <= entryText.length; i++) {\n    if (documentText.substr(-i) === entryText.substr(0, i)) {\n      triggerOffset = i;\n    }\n  }\n  return triggerOffset;\n}\n\nfunction $isCurrentSelectionAtBoundary(offset: number): boolean {\n  // If the offset is not zero, i.e. not at the beginning of the text node, the selection is somewhere in the middle of the entity, i.e. not at the boundary.\n  if (offset !== 0) return false;\n\n  // Othewise (if the offset is zero), it means the selection could be at the start of an entity. It could also be at the end of the previous entity, or it could be in a position where there are no entities at all.\n  // So, we check if the previous sibling of the node at the anchor of the selection is a text entity. If it is, then the selection is at the boundary of the entity.\n  const selection = $getSelection();\n\n  if (!$isRangeSelection(selection)) return false;\n\n  const anchor = selection.anchor.getNode();\n  const prevSibling = anchor.getPreviousSibling();\n\n  if (!$isTextNode(prevSibling)) return false;\n  if (!prevSibling.isTextEntity()) return false;\n\n  return true;\n}\n\nfunction $getRangeAtMatch(match: RegExpExecArray): globalThis.Range | null {\n  const offsetWithWhitespaces = match.index + match[1].length;\n\n  if ($isCurrentSelectionAtBoundary(offsetWithWhitespaces)) return null;\n\n  const selection = window.getSelection();\n  if (selection === null) return null;\n  if (!selection.isCollapsed) return null;\n\n  const anchor = selection.anchorNode;\n  if (anchor === null) return null;\n\n  const endOffset = selection.anchorOffset;\n  if (endOffset === null) return null;\n\n  const range = document.createRange();\n\n  try {\n    range.setStart(anchor, offsetWithWhitespaces);\n    range.setEnd(anchor, endOffset);\n    return range;\n  } catch {\n    return null;\n  }\n}\n\nexport function MentionPlugin() {\n  const [editor] = useLexicalComposerContext();\n  const room = useRoom();\n\n  const [match, setMatch] = useState<RegExpExecArray | null>(null); // Represents the current match of the mention regex. A `null` value means there is no match.\n  const matchingString = match?.[3];\n\n  const suggestions = useMentionSuggestions(room.id, matchingString);\n  const createTextMention = useCreateTextMention();\n  const deleteTextMention = useDeleteTextMention();\n\n  useEffect(() => {\n    function $handleMentionMutation(\n      mutations: Map<NodeKey, NodeMutation>,\n      {\n        prevEditorState,\n      }: {\n        prevEditorState: EditorState;\n      }\n    ) {\n      for (const [key, mutation] of mutations) {\n        if (mutation === \"created\") {\n          editor.getEditorState().read(() => {\n            const node = $getNodeByKey(key);\n            if (node === null) return;\n\n            if ($isMentionNode(node)) {\n              createTextMention(node.getId(), {\n                kind: \"user\",\n                id: node.getUserId(),\n              });\n            }\n          });\n        } else if (mutation === \"destroyed\") {\n          prevEditorState.read(() => {\n            const node = $getNodeByKey(key);\n            if (node === null) return;\n\n            if ($isMentionNode(node)) {\n              deleteTextMention(node.getId());\n            }\n          });\n        }\n      }\n    }\n\n    function $handleGroupMentionMutation(\n      mutations: Map<NodeKey, NodeMutation>,\n      {\n        prevEditorState,\n      }: {\n        prevEditorState: EditorState;\n      }\n    ) {\n      for (const [key, mutation] of mutations) {\n        if (mutation === \"created\") {\n          editor.getEditorState().read(() => {\n            const node = $getNodeByKey(key);\n            if (node === null) return;\n\n            if ($isGroupMentionNode(node)) {\n              createTextMention(node.getId(), {\n                kind: \"group\",\n                id: node.getGroupId(),\n                userIds: node.getUserIds(),\n              });\n            }\n          });\n        } else if (mutation === \"destroyed\") {\n          prevEditorState.read(() => {\n            const node = $getNodeByKey(key);\n            if (node === null) return;\n\n            if ($isGroupMentionNode(node)) {\n              deleteTextMention(node.getId());\n            }\n          });\n        }\n      }\n    }\n\n    const unsubscribeMentionMutationListener = editor.registerMutationListener(\n      MentionNode,\n      (mutations, payload) => {\n        // Ignore mutations to MentionNode (creation/updates/deletions) that are caused by collaboration (remote users) or history merge.\n        if (\n          payload.updateTags.has(\"collaboration\") ||\n          payload.updateTags.has(\"history-merge\")\n        ) {\n          return;\n        }\n\n        $handleMentionMutation(mutations, payload);\n      }\n    );\n\n    const unsubscribeGroupMentionMutationListener =\n      editor.registerMutationListener(\n        GroupMentionNode,\n        (mutations, payload) => {\n          // Ignore mutations to GroupMentionNode (creation/updates/deletions) that are caused by collaboration (remote users) or history merge.\n          if (\n            payload.updateTags.has(\"collaboration\") ||\n            payload.updateTags.has(\"history-merge\")\n          ) {\n            return;\n          }\n\n          $handleGroupMentionMutation(mutations, payload);\n        }\n      );\n\n    return () => {\n      unsubscribeMentionMutationListener();\n      unsubscribeGroupMentionMutationListener();\n    };\n  }, [editor, createTextMention, deleteTextMention]);\n\n  useEffect(() => {\n    function $onStateRead() {\n      const text = $getAnchorNodeTextContent();\n      if (text === null) {\n        setMatch(null);\n        return;\n      }\n\n      const match = MentionRegex.exec(text);\n      setMatch(match);\n    }\n\n    return editor.registerUpdateListener(({ editorState: state }) => {\n      state.read($onStateRead);\n    });\n  }, [editor]);\n\n  useEffect(() => {\n    function $handleBackspace(event: KeyboardEvent): boolean {\n      const selection = $getSelection();\n\n      if (selection === null) return false;\n\n      // If the selection is a node selection and the only node selected is a mention node, then we replace the mention node with a text node containing \"@\" and set the selection at the end of the text node.\n      if ($isNodeSelection(selection)) {\n        const nodes = selection.getNodes();\n        if (nodes.length !== 1) return false;\n\n        const node = nodes[0];\n        if (!$isMentionNode(node) && !$isGroupMentionNode(node)) {\n          return false;\n        }\n\n        const text = $createTextNode(\"@\");\n        node.replace(text);\n\n        const newSelection = $createRangeSelection();\n        newSelection.setTextNodeRange(text, 1, text, 1);\n        $setSelection(newSelection);\n\n        event.preventDefault();\n        return true;\n      } else if ($isRangeSelection(selection)) {\n        if (!selection.isCollapsed()) return false;\n\n        const anchor = selection.anchor.getNode();\n        const prevSibling = anchor.getPreviousSibling();\n        if (\n          selection.anchor.offset === 0 &&\n          ($isMentionNode(prevSibling) || $isGroupMentionNode(prevSibling))\n        ) {\n          const text = $createTextNode(\"@\");\n          prevSibling.replace(text);\n\n          const newSelection = $createRangeSelection();\n          newSelection.setTextNodeRange(text, 1, text, 1);\n          $setSelection(newSelection);\n\n          event.preventDefault();\n          return true;\n        } else if ($isElementNode(anchor)) {\n          const child = anchor.getChildAtIndex(selection.anchor.offset - 1);\n          if (!$isMentionNode(child) && !$isGroupMentionNode(child)) {\n            return false;\n          }\n\n          const text = $createTextNode(\"@\");\n          child.replace(text);\n\n          const newSelection = $createRangeSelection();\n          newSelection.setTextNodeRange(text, 1, text, 1);\n          $setSelection(newSelection);\n\n          event.preventDefault();\n          return true;\n        }\n\n        return false;\n      }\n\n      return false;\n    }\n\n    return editor.registerCommand(\n      KEY_BACKSPACE_COMMAND,\n      $handleBackspace,\n      COMMAND_PRIORITY_LOW\n    );\n  }, [editor]);\n\n  const handleSuggestionSelect = useCallback(\n    (mention: MentionData) => {\n      function $onValueSelect() {\n        if (match === null) return;\n\n        setMatch(null);\n\n        const selection = $getSelection();\n\n        if (!$isRangeSelection(selection)) return;\n        if (!selection.isCollapsed()) return;\n\n        const anchor = selection.anchor;\n        if (anchor.type !== \"text\") return;\n\n        const anchorNode: TextNode = anchor.getNode();\n        if (!anchorNode.isSimpleText()) return;\n\n        const selectionOffset = anchor.offset;\n        const text = anchorNode.getTextContent().slice(0, selectionOffset);\n\n        const characterOffset = match[2].length;\n        const queryOffset = getFullMatchOffset(text, match[2], characterOffset);\n        const startOffset = selectionOffset - queryOffset;\n        if (startOffset < 0) return;\n\n        let mentionNode: MentionNode | GroupMentionNode;\n\n        switch (mention.kind) {\n          case \"user\":\n            mentionNode = $createMentionNode(mention.id);\n            break;\n\n          case \"group\":\n            mentionNode = $createGroupMentionNode(mention.id, mention.userIds);\n            break;\n\n          default:\n            return assertNever(mention, \"Unhandled mention kind\");\n        }\n\n        // Split the anchor (text) node and create a new text node only containing matched text.\n        if (startOffset === 0) {\n          const [node] = anchorNode.splitText(selectionOffset);\n          node.replace(mentionNode);\n        } else {\n          const [, node] = anchorNode.splitText(startOffset, selectionOffset);\n          node.replace(mentionNode);\n        }\n      }\n\n      editor.update($onValueSelect);\n    },\n    [editor, match]\n  );\n\n  if (match === null || matchingString === undefined) return null;\n\n  if (suggestions === undefined || suggestions.length === 0) return null;\n\n  const range = editor.getEditorState().read(() => $getRangeAtMatch(match));\n\n  if (range === null) return null;\n\n  return (\n    <SuggestionsContext.Provider value={suggestions}>\n      <OnSuggestionSelectCallbackContext.Provider\n        value={handleSuggestionSelect}\n      >\n        <OnResetMatchCallbackContext.Provider value={() => setMatch(null)}>\n          <SuggestionsPortal range={range} key={matchingString}>\n            <Suggestions.List className=\"lb-lexical-suggestions-list lb-lexical-mention-suggestions-list\">\n              {suggestions.map((mention) => {\n                return (\n                  <Suggestions.Item\n                    key={mention.id}\n                    value={mention.id}\n                    className=\"lb-lexical-suggestions-list-item lb-lexical-mention-suggestion\"\n                  >\n                    {mention.kind === \"user\" ? (\n                      <>\n                        <UserAvatar\n                          userId={mention.id}\n                          className=\"lb-lexical-mention-suggestion-avatar\"\n                        />\n                        <User\n                          userId={mention.id}\n                          className=\"lb-lexical-mention-suggestion-user\"\n                        />\n                      </>\n                    ) : mention.kind === \"group\" ? (\n                      <>\n                        <GroupAvatar\n                          groupId={mention.id}\n                          className=\"lb-lexical-mention-suggestion-avatar\"\n                          icon={<UsersIcon />}\n                        />\n                        <Group\n                          groupId={mention.id}\n                          className=\"lb-lexical-mention-suggestion-group\"\n                        >\n                          <GroupDescription\n                            groupId={mention.id}\n                            className=\"lb-lexical-mention-suggestion-group-description\"\n                          />\n                        </Group>\n                      </>\n                    ) : (\n                      assertNever(mention, \"Unhandled mention kind\")\n                    )}\n                  </Suggestions.Item>\n                );\n              })}\n            </Suggestions.List>\n          </SuggestionsPortal>\n        </OnResetMatchCallbackContext.Provider>\n      </OnSuggestionSelectCallbackContext.Provider>\n    </SuggestionsContext.Provider>\n  );\n}\n\nexport const SUGGESTIONS_COLLISION_PADDING = 10;\n\nfunction SuggestionsPortal({\n  children,\n  range,\n}: {\n  children: ReactNode;\n  range: Range;\n}) {\n  const {\n    refs: { setReference, setFloating },\n    strategy,\n    x,\n    y,\n  } = useFloating({\n    strategy: \"fixed\",\n    placement: \"top-start\",\n    middleware: [\n      flip({ padding: SUGGESTIONS_COLLISION_PADDING, crossAxis: false }),\n      offset(10),\n      hide({ padding: SUGGESTIONS_COLLISION_PADDING }),\n      shift({ padding: SUGGESTIONS_COLLISION_PADDING, limiter: limitShift() }),\n      size({ padding: SUGGESTIONS_COLLISION_PADDING }),\n    ],\n    whileElementsMounted: (...args) => {\n      return autoUpdate(...args, {\n        animationFrame: true,\n      });\n    },\n  });\n\n  useLayoutEffect(() => {\n    setReference({\n      getBoundingClientRect: () => range.getBoundingClientRect(),\n    });\n  }, [setReference, range]);\n\n  return (\n    <Portal asChild>\n      <div\n        ref={setFloating}\n        style={{\n          position: strategy,\n          top: 0,\n          left: 0,\n          transform: `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`,\n          minWidth: \"max-content\",\n        }}\n        className=\"lb-root lb-portal lb-elevation lb-lexical-suggestions lb-lexical-mention-suggestions\"\n      >\n        {children}\n      </div>\n    </Portal>\n  );\n}\n"],"names":["MENTION_CHARACTER","$getSelection","$isRangeSelection","offset","$isTextNode","useLexicalComposerContext","useRoom","useState","suggestions","useMentionSuggestions","useCreateTextMention","useDeleteTextMention","useEffect","$getNodeByKey","$isMentionNode","$isGroupMentionNode","MentionNode","GroupMentionNode","match","$isNodeSelection","$createTextNode","$createRangeSelection","$setSelection","$isElementNode","KEY_BACKSPACE_COMMAND","COMMAND_PRIORITY_LOW","useCallback","mentionNode","$createMentionNode","$createGroupMentionNode","assertNever","jsx","SuggestionsContext","OnSuggestionSelectCallbackContext","OnResetMatchCallbackContext","Suggestions.List","Suggestions.Item","jsxs","Fragment","UserAvatar","User","GroupAvatar","UsersIcon","Group","GroupDescription","useFloating","flip","hide","shift","limitShift","size","autoUpdate","useLayoutEffect","Portal"],"mappings":"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"}