{"version":3,"file":"suggestions.mjs","sources":["../../../src/slate-plugins/suggestions.tsx"],"sourcesContent":["import { debounce, sortBy } from 'lodash';\nimport { Editor, Plugin as SlatePlugin } from 'slate-react';\n\nimport { BootData } from '@grafana/data';\n\nimport { Typeahead } from '../components/Typeahead/Typeahead';\nimport { CompletionItem, SuggestionsState, TypeaheadInput, TypeaheadOutput } from '../types';\nimport { makeFragment, SearchFunctionType } from '../utils';\nimport { SearchFunctionMap } from '../utils/searchFunctions';\n\nimport TOKEN_MARK from './slate-prism/TOKEN_MARK';\n\nexport const TYPEAHEAD_DEBOUNCE = 250;\n\ndeclare global {\n  interface Window {\n    grafanaBootData?: BootData;\n  }\n}\n\n// Commands added to the editor by this plugin.\ninterface SuggestionsPluginCommands {\n  selectSuggestion: (suggestion: CompletionItem) => Editor;\n  applyTypeahead: (suggestion: CompletionItem) => Editor;\n}\n\nexport function SuggestionsPlugin({\n  onTypeahead,\n  cleanText,\n  onWillApplySuggestion,\n  portalOrigin,\n}: {\n  onTypeahead?: (typeahead: TypeaheadInput) => Promise<TypeaheadOutput>;\n  cleanText?: (text: string) => string;\n  onWillApplySuggestion?: (suggestion: string, state: SuggestionsState) => string;\n  portalOrigin: string;\n}): SlatePlugin {\n  let typeaheadRef: Typeahead;\n  let state: SuggestionsState = {\n    groupedItems: [],\n    typeaheadPrefix: '',\n    typeaheadContext: '',\n    typeaheadText: '',\n  };\n  const handleTypeaheadDebounced = debounce(handleTypeahead, TYPEAHEAD_DEBOUNCE);\n\n  const setState = (update: Partial<SuggestionsState>) => {\n    state = {\n      ...state,\n      ...update,\n    };\n  };\n\n  return {\n    onBlur: (event, editor, next) => {\n      state = {\n        ...state,\n        groupedItems: [],\n      };\n\n      return next();\n    },\n\n    onClick: (event, editor, next) => {\n      state = {\n        ...state,\n        groupedItems: [],\n      };\n\n      return next();\n    },\n\n    onKeyDown: (event, editor, next) => {\n      const currentSuggestions = state.groupedItems;\n\n      const hasSuggestions = currentSuggestions.length;\n\n      switch (event.key) {\n        case 'Escape': {\n          if (hasSuggestions) {\n            event.preventDefault();\n\n            state = {\n              ...state,\n              groupedItems: [],\n            };\n\n            // Bogus edit to re-render editor\n            return editor.insertText('');\n          }\n\n          break;\n        }\n\n        case 'ArrowDown':\n        case 'ArrowUp':\n          if (hasSuggestions) {\n            event.preventDefault();\n            typeaheadRef.moveMenuIndex(event.key === 'ArrowDown' ? 1 : -1);\n            return;\n          }\n\n          break;\n\n        case 'Enter': {\n          if (!(event.shiftKey || event.ctrlKey) && hasSuggestions) {\n            event.preventDefault();\n            return typeaheadRef.insertSuggestion();\n          }\n\n          break;\n        }\n\n        case 'Tab': {\n          if (hasSuggestions) {\n            event.preventDefault();\n            return typeaheadRef.insertSuggestion();\n          }\n\n          break;\n        }\n\n        default: {\n          // Don't react on meta keys\n          if (event.key.length === 1) {\n            handleTypeaheadDebounced(editor, setState, onTypeahead, cleanText);\n          }\n          break;\n        }\n      }\n\n      return next();\n    },\n\n    commands: {\n      selectSuggestion: (editor, suggestion: CompletionItem): Editor => {\n        const suggestions = state.groupedItems;\n        if (!suggestions || !suggestions.length) {\n          return editor;\n        }\n\n        // @ts-ignore\n        const ed = editor.applyTypeahead(suggestion);\n        handleTypeaheadDebounced(editor, setState, onTypeahead, cleanText);\n        return ed;\n      },\n\n      applyTypeahead: (editor, suggestion: CompletionItem) => {\n        let suggestionText = suggestion.insertText || suggestion.label;\n\n        const preserveSuffix = suggestion.kind === 'function';\n        const move = suggestion.move || 0;\n        const moveForward = move > 0 ? move : 0;\n        const moveBackward = move < 0 ? -move : 0;\n\n        const { typeaheadPrefix, typeaheadText, typeaheadContext } = state;\n\n        if (onWillApplySuggestion) {\n          suggestionText = onWillApplySuggestion(suggestionText, {\n            groupedItems: state.groupedItems,\n            typeaheadContext,\n            typeaheadPrefix,\n            typeaheadText,\n          });\n        }\n\n        const { forward, backward } = getNumCharsToDelete(\n          suggestionText,\n          typeaheadPrefix,\n          typeaheadText,\n          preserveSuffix,\n          suggestion.deleteBackwards,\n          cleanText\n        );\n\n        // If new-lines, apply suggestion as block\n        if (suggestionText.match(/\\n/)) {\n          const fragment = makeFragment(suggestionText);\n          editor.deleteBackward(backward).deleteForward(forward).insertFragment(fragment).focus();\n          return editor;\n        }\n\n        state = {\n          ...state,\n          groupedItems: [],\n        };\n\n        editor\n          .snapshotSelection()\n          .deleteBackward(backward)\n          .deleteForward(forward)\n          .insertText(suggestionText)\n          .moveForward(moveForward)\n          .moveBackward(moveBackward)\n          .focus();\n\n        return editor;\n      },\n    },\n\n    renderEditor(props, editor, next) {\n      if (editor.value.selection.isExpanded) {\n        return next();\n      }\n\n      const children = next();\n\n      return (\n        <>\n          {children}\n          <Typeahead\n            menuRef={(menu: Typeahead) => (typeaheadRef = menu)}\n            origin={portalOrigin}\n            prefix={state.typeaheadPrefix}\n            isOpen={!!state.groupedItems.length}\n            groupedItems={state.groupedItems}\n            onSelectSuggestion={(editor as Editor & SuggestionsPluginCommands).selectSuggestion}\n          />\n        </>\n      );\n    },\n  };\n}\n\nconst handleTypeahead = async (\n  editor: Editor,\n  onStateChange: (state: Partial<SuggestionsState>) => void,\n  onTypeahead?: (typeahead: TypeaheadInput) => Promise<TypeaheadOutput>,\n  cleanText?: (text: string) => string\n): Promise<void> => {\n  if (!onTypeahead) {\n    return;\n  }\n\n  const { value } = editor;\n  const { selection } = value;\n\n  // Get decorations associated with the current line\n  const parentBlock = value.document.getClosestBlock(value.focusBlock.key);\n  const selectionStartOffset = value.selection.start.offset - 1;\n  const decorations = parentBlock && parentBlock.getDecorations(editor as any);\n\n  const filteredDecorations = decorations\n    ? decorations\n        .filter(\n          (decoration) =>\n            decoration!.start.offset <= selectionStartOffset &&\n            decoration!.end.offset > selectionStartOffset &&\n            decoration!.type === TOKEN_MARK\n        )\n        .toArray()\n    : [];\n\n  // Find the first label key to the left of the cursor\n  const labelKeyDec =\n    decorations &&\n    decorations\n      .filter(\n        (decoration) =>\n          decoration!.end.offset <= selectionStartOffset &&\n          decoration!.type === TOKEN_MARK &&\n          decoration!.data.get('className').includes('label-key')\n      )\n      .last();\n\n  const labelKey = labelKeyDec && value.focusText.text.slice(labelKeyDec.start.offset, labelKeyDec.end.offset);\n\n  const wrapperClasses = filteredDecorations\n    .map((decoration) => decoration.data.get('className'))\n    .join(' ')\n    .split(' ')\n    .filter((className) => className.length);\n\n  let text = value.focusText.text;\n  let prefix = text.slice(0, selection.focus.offset);\n\n  if (filteredDecorations.length) {\n    text = value.focusText.text.slice(filteredDecorations[0].start.offset, filteredDecorations[0].end.offset);\n    prefix = value.focusText.text.slice(filteredDecorations[0].start.offset, selection.focus.offset);\n  }\n\n  // Label values could have valid characters erased if `cleanText()` is\n  // blindly applied, which would undesirably interfere with suggestions\n  const labelValueMatch = prefix.match(/(?:!?=~?\"?|\")(.*)/);\n  if (labelValueMatch) {\n    prefix = labelValueMatch[1];\n  } else if (cleanText) {\n    prefix = cleanText(prefix);\n  }\n\n  const { suggestions, context } = await onTypeahead({\n    prefix,\n    text,\n    value,\n    wrapperClasses,\n    labelKey: labelKey || undefined,\n    editor,\n  });\n\n  const filteredSuggestions = suggestions\n    .map((group) => {\n      if (!group.items) {\n        return group;\n      }\n      // Falling back to deprecated prefixMatch to support backwards compatibility with plugins using this property\n      const searchFunctionType =\n        group.searchFunctionType || (group.prefixMatch ? SearchFunctionType.Prefix : SearchFunctionType.Word);\n      const searchFunction = SearchFunctionMap[searchFunctionType];\n      let newGroup = { ...group };\n      if (prefix) {\n        // Filter groups based on prefix\n        if (!group.skipFilter) {\n          newGroup.items = newGroup.items.filter((c) => (c.filterText || c.label).length >= prefix.length);\n          newGroup.items = searchFunction(newGroup.items, prefix);\n        }\n\n        // Filter out the already typed value (prefix) unless it inserts custom text not matching the prefix\n        newGroup.items = newGroup.items.filter(\n          (c) => !(c.insertText === prefix || (c.filterText ?? c.label) === prefix)\n        );\n      }\n\n      if (!group.skipSort) {\n        newGroup.items = sortBy(newGroup.items, (item: CompletionItem) => {\n          if (item.sortText === undefined) {\n            return item.sortValue !== undefined ? item.sortValue : item.label;\n          } else {\n            // Falling back to deprecated sortText to support backwards compatibility with plugins using this property\n            return item.sortText || item.label;\n          }\n        });\n      }\n\n      return newGroup;\n    })\n    .filter((gr) => gr.items && gr.items.length); // Filter out empty groups\n\n  onStateChange({\n    groupedItems: filteredSuggestions,\n    typeaheadPrefix: prefix,\n    typeaheadContext: context,\n    typeaheadText: text,\n  });\n\n  // Bogus edit to force re-render\n  editor.blur().focus();\n};\n\nexport function getNumCharsToDelete(\n  suggestionText: string,\n  typeaheadPrefix: string,\n  typeaheadText: string,\n  preserveSuffix: boolean,\n  deleteBackwards?: number,\n  cleanText?: (text: string) => string\n) {\n  // remove the current, incomplete text and replace it with the selected suggestion\n  const backward = deleteBackwards || typeaheadPrefix.length;\n  const text = cleanText ? cleanText(typeaheadText) : typeaheadText;\n  const offset = typeaheadText.indexOf(typeaheadPrefix);\n\n  const suffixLength =\n    offset > -1 ? text.length - offset - typeaheadPrefix.length : text.length - typeaheadPrefix.length;\n  const midWord = Boolean((typeaheadPrefix && suffixLength > 0) || suggestionText === typeaheadText);\n  const forward = midWord && !preserveSuffix ? suffixLength + offset : 0;\n\n  return {\n    forward,\n    backward,\n  };\n}\n"],"names":[],"mappings":"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"}