{"version":3,"file":"suggestion-plugin.cjs","sources":["../../../components/editor/suggestion-plugin.ts"],"sourcesContent":["import {\n  type EditorState,\n  Plugin,\n  PluginKey,\n  TextSelection\n} from 'prosemirror-state';\nimport { Decoration, DecorationSet, type EditorView } from 'prosemirror-view';\nimport styles from './editor.module.css';\nimport type { MentionAttrs } from './mention';\nimport { editorSchema, mentionType } from './schema';\n\n/** The active trigger and the query the user is typing after it. */\nexport interface SuggestionState {\n  trigger: string;\n  /** Text between the trigger and the caret. May contain spaces. */\n  query: string;\n  /** Document position of the trigger character. */\n  from: number;\n  /** Document position of the caret — the end of the query. */\n  to: number;\n}\n\ninterface SuggestionPluginState {\n  active: SuggestionState | null;\n  /**\n   * A range the user dismissed with Escape or the space-cancel rule. Blocks\n   * re-detection until the query changes, so the menu does not spring back.\n   */\n  dismissed: { from: number; query: string } | null;\n}\n\nexport interface SuggestionPluginOptions {\n  /** Trigger characters that are currently registered. */\n  getTriggers: () => string[];\n  /** Notified whenever the active query changes. */\n  onStateChange: (state: SuggestionState | null) => void;\n  /**\n   * Called for every keydown while a query is active. Return true to consume\n   * the key — the handler owns `preventDefault` and `stopPropagation`.\n   */\n  onKeyDown: (event: KeyboardEvent, state: SuggestionState) => boolean;\n}\n\nexport const suggestionPluginKey = new PluginKey<SuggestionPluginState>(\n  'apsara-suggestion'\n);\n\n/**\n * Stands in for atoms and hard breaks while scanning text, so a chip or a line\n * break reads as one non-word character and ends a query.\n */\nconst OBJECT = '￼';\n\n/** Nothing plausible is a mention query past this many characters. */\nconst MAX_QUERY_LENGTH = 120;\n\nfunction isBoundary(char: string): boolean {\n  return char === '' || char === OBJECT || /\\s/.test(char);\n}\n\n/**\n * Looks backwards from the caret for a trigger at a word boundary. Stops at\n * whitespace, so only a single-word query can *start* a menu — a query that\n * already contains a space is carried forward by the active state instead.\n */\nfunction detect(\n  selection: TextSelection,\n  triggers: string[]\n): SuggestionState | null {\n  if (!selection.empty || triggers.length === 0) return null;\n  const $from = selection.$from;\n  if (!$from.parent.isTextblock) return null;\n\n  const before = $from.parent.textBetween(\n    0,\n    $from.parentOffset,\n    OBJECT,\n    OBJECT\n  );\n  const blockStart = $from.start();\n  const stop = Math.max(0, before.length - MAX_QUERY_LENGTH);\n\n  for (let index = before.length - 1; index >= stop; index -= 1) {\n    const char = before[index];\n    if (char === OBJECT) break;\n    if (triggers.includes(char)) {\n      if (!isBoundary(index === 0 ? '' : before[index - 1])) continue;\n      return {\n        trigger: char,\n        query: before.slice(index + 1),\n        from: blockStart + index,\n        to: blockStart + before.length\n      };\n    }\n    if (/\\s/.test(char)) break;\n  }\n\n  return null;\n}\n\n/**\n * Carries an active query across a transaction. Returns null when the query\n * can no longer be extended — the trigger was deleted, the caret left the\n * range, or a chip or line break landed inside it.\n */\nfunction carry(\n  active: SuggestionState,\n  from: number,\n  state: EditorState\n): SuggestionState | null {\n  if (!state.selection.empty) return null;\n  const to = state.selection.from;\n  if (from < 0 || from + 1 > state.doc.content.size || to <= from) return null;\n\n  const $from = state.doc.resolve(from);\n  const $to = state.doc.resolve(to);\n  if (!$from.parent.isTextblock || $from.start() !== $to.start()) return null;\n  if (\n    state.doc.textBetween(from, from + 1, OBJECT, OBJECT) !== active.trigger\n  ) {\n    return null;\n  }\n\n  const query = state.doc.textBetween(from + 1, to, OBJECT, OBJECT);\n  if (query.includes(OBJECT)) return null;\n\n  return { trigger: active.trigger, query, from, to };\n}\n\nfunction sameState(\n  a: SuggestionState | null,\n  b: SuggestionState | null\n): boolean {\n  if (a === b) return true;\n  if (!a || !b) return false;\n  return (\n    a.trigger === b.trigger &&\n    a.query === b.query &&\n    a.from === b.from &&\n    a.to === b.to\n  );\n}\n\nexport function suggestionPlugin(options: SuggestionPluginOptions): Plugin {\n  // IME state is a view concern, not document state: a composition can span\n  // several transactions and must never open the menu part-way through.\n  let composing = false;\n\n  return new Plugin<SuggestionPluginState>({\n    key: suggestionPluginKey,\n\n    state: {\n      init: () => ({ active: null, dismissed: null }),\n\n      apply(tr, previous, _old, next) {\n        const meta = tr.getMeta(suggestionPluginKey) as\n          | { type: 'dismiss' }\n          | undefined;\n\n        let dismissed = previous.dismissed\n          ? {\n              ...previous.dismissed,\n              from: tr.mapping.map(previous.dismissed.from, -1)\n            }\n          : null;\n\n        if (meta?.type === 'dismiss') {\n          return {\n            active: null,\n            dismissed: previous.active\n              ? { from: previous.active.from, query: previous.active.query }\n              : dismissed\n          };\n        }\n\n        if (previous.active) {\n          const carried = carry(\n            previous.active,\n            tr.mapping.map(previous.active.from, -1),\n            next\n          );\n          if (carried) return { active: carried, dismissed };\n        }\n\n        if (composing) return { active: null, dismissed };\n\n        const detected =\n          next.selection instanceof TextSelection\n            ? detect(next.selection, options.getTriggers())\n            : null;\n\n        if (\n          detected &&\n          dismissed &&\n          dismissed.from === detected.from &&\n          dismissed.query === detected.query\n        ) {\n          return { active: null, dismissed };\n        }\n\n        if (detected) dismissed = null;\n        return { active: detected, dismissed };\n      }\n    },\n\n    props: {\n      handleKeyDown(view, event) {\n        const active = suggestionPluginKey.getState(view.state)?.active;\n        if (!active) return false;\n        return options.onKeyDown(event, active);\n      },\n\n      handleDOMEvents: {\n        compositionstart: () => {\n          composing = true;\n          return false;\n        },\n        compositionend: () => {\n          composing = false;\n          return false;\n        }\n      },\n\n      // The trigger and its query read as pending rather than as ordinary\n      // text while the menu is open.\n      decorations(state) {\n        const active = suggestionPluginKey.getState(state)?.active;\n        if (!active) return null;\n        return DecorationSet.create(state.doc, [\n          Decoration.inline(active.from, active.to, {\n            class: styles.activeSuggestion\n          })\n        ]);\n      }\n    },\n\n    view() {\n      let last: SuggestionState | null = null;\n      return {\n        update(view) {\n          const active =\n            suggestionPluginKey.getState(view.state)?.active ?? null;\n          if (sameState(active, last)) return;\n          last = active;\n          options.onStateChange(active);\n        },\n        destroy() {\n          if (last) options.onStateChange(null);\n        }\n      };\n    }\n  });\n}\n\n/** Closes the menu and leaves the typed text literal. */\nexport function dismissSuggestion(view: EditorView): void {\n  view.dispatch(\n    view.state.tr.setMeta(suggestionPluginKey, { type: 'dismiss' })\n  );\n}\n\nfunction isWhitespaceAt(state: EditorState, position: number): boolean {\n  if (position >= state.doc.content.size) return false;\n  return /\\s/.test(\n    state.doc.textBetween(position, position + 1, OBJECT, OBJECT)\n  );\n}\n\n/**\n * Replaces `range` with a chip followed by a single space, caret after it.\n * With no range the chip lands at the caret.\n */\nexport function insertMention(\n  view: EditorView,\n  attrs: MentionAttrs,\n  range?: { from: number; to: number }\n): void {\n  const { state } = view;\n  const target = range ?? {\n    from: state.selection.from,\n    to: state.selection.to\n  };\n\n  const tr = state.tr;\n  const nodes = [mentionType.create(attrs)];\n  // Skip the trailing space when the caret already sits in front of one, so\n  // picking a mention mid-sentence does not leave a gap.\n  const spaced = isWhitespaceAt(state, target.to);\n  if (!spaced) nodes.push(editorSchema.text(' '));\n\n  tr.replaceWith(target.from, target.to, nodes);\n  const caret = Math.min(target.from + (spaced ? 1 : 2), tr.doc.content.size);\n  tr.setSelection(TextSelection.create(tr.doc, caret));\n  tr.scrollIntoView();\n  view.dispatch(tr);\n}\n"],"names":["PluginKey","Plugin","TextSelection","DecorationSet","Decoration","styles","mentionType","editorSchema"],"mappings":"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"}