UNPKG

text-editor-studio-ts

Version:

A powerful mobile-responsive rich text editor built with Lexical and React

1,983 lines 814 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import { jsx, jsxs, Fragment } from "react/jsx-runtime"; import * as React from "react"; import React__default, { useContext, createContext, useMemo, useLayoutEffect, useEffect, useState, useCallback, useRef, Suspense, forwardRef, lazy } from "react"; import { createEditor, $getRoot, $createParagraphNode, $getSelection, $isNodeSelection, $createNodeSelection, $setSelection, $getNodeByKey, DecoratorNode, $applyNodeReplacement, CLICK_COMMAND, COMMAND_PRIORITY_LOW as COMMAND_PRIORITY_LOW$1, createCommand, KEY_TAB_COMMAND, KEY_ARROW_RIGHT_COMMAND, $isRangeSelection, $isTextNode, $createTextNode, ElementNode, isHTMLElement, $isElementNode, FORMAT_ELEMENT_COMMAND, TextNode, COMMAND_PRIORITY_HIGH, KEY_DELETE_COMMAND, KEY_BACKSPACE_COMMAND, ParagraphNode, isDOMNode, getNearestEditorFromDOMNode, $getNearestNodeFromDOMNode, UNDO_COMMAND, CAN_REDO_COMMAND, CAN_UNDO_COMMAND, COMMAND_PRIORITY_EDITOR, REDO_COMMAND, CLEAR_EDITOR_COMMAND, CLEAR_HISTORY_COMMAND, $isRootNode, $isBlockElementNode, $createRangeSelection, $normalizeSelection__EXPERIMENTAL, OUTDENT_CONTENT_COMMAND, INDENT_CONTENT_COMMAND, INSERT_TAB_COMMAND, COMMAND_PRIORITY_CRITICAL, SELECTION_CHANGE_COMMAND, $isRootOrShadowRoot, DELETE_CHARACTER_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ARROW_LEFT_COMMAND, INSERT_PARAGRAPH_COMMAND, KEY_ESCAPE_COMMAND, KEY_ENTER_COMMAND, $insertNodes, DRAGSTART_COMMAND, DRAGOVER_COMMAND, DROP_COMMAND, FORMAT_TEXT_COMMAND, KEY_MODIFIER_COMMAND, COMMAND_PRIORITY_NORMAL, $isLineBreakNode, getDOMSelection as getDOMSelection$2, COPY_COMMAND, CUT_COMMAND, PASTE_COMMAND, $isParagraphNode, FOCUS_COMMAND } from "lexical"; import { $generateHtmlFromNodes } from "@lexical/html"; import * as TooltipPrimitive from "@radix-ui/react-tooltip"; import { clsx } from "clsx"; import { twMerge } from "tailwind-merge"; import { CodeNode, CodeHighlightNode, $createCodeNode, CODE_LANGUAGE_FRIENDLY_NAME_MAP, $isCodeNode, getLanguageFriendlyName, CODE_LANGUAGE_MAP, registerCodeHighlighting, $isCodeHighlightNode } from "@lexical/code"; import { HashtagNode, $createHashtagNode } from "@lexical/hashtag"; import { LinkNode, AutoLinkNode, $isLinkNode, TOGGLE_LINK_COMMAND, $isAutoLinkNode, $createAutoLinkNode, $createLinkNode, $toggleLink } from "@lexical/link"; import { ListNode, ListItemNode, registerCheckList, registerListStrictIndentTransform, registerList, $isListNode, INSERT_UNORDERED_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, $getListDepth, $isListItemNode } from "@lexical/list"; import { OverflowNode } from "@lexical/overflow"; import { addClassNamesToElement, mergeRegister, removeClassNamesFromElement, $getNearestBlockElementAncestorOrThrow, $findMatchingParent, isHTMLAnchorElement, $insertNodeToNearestRoot, $filter, $getNearestNodeOfType, $wrapNodeInElement, calculateZoomLevel, mediaFileReader, isMimeType, isHTMLElement as isHTMLElement$1, objectKlassEquals } from "@lexical/utils"; import { HeadingNode, QuoteNode, registerRichText, $isHeadingNode, $createHeadingNode, $createQuoteNode, $isQuoteNode, DRAG_DROP_PASTE, eventFiles } from "@lexical/rich-text"; import { TableNode, TableCellNode, TableRowNode, setScrollableTablesActive, registerTablePlugin, registerTableSelectionObserver, registerTableCellUnmergeTransform, INSERT_TABLE_COMMAND, $isTableSelection, $getTableCellNodeFromLexicalNode, $getTableNodeFromLexicalNodeOrThrow, getTableObserverFromTableElement, $insertTableRow__EXPERIMENTAL, $insertTableColumn__EXPERIMENTAL, $deleteTableRow__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL, $getTableRowIndexFromTableCellNode, $isTableRowNode, TableCellHeaderStates, $isTableCellNode, $getTableColumnIndexFromTableCellNode, $getNodeTriplet, $unmergeCell, $computeTableMapSkipCellCheck, getDOMCellFromTarget, $isTableNode, $createTableNode, $createTableRowNode, $createTableCellNode } from "@lexical/table"; import { $isAtNodeEnd, $setBlocksType, $patchStyleText, $getSelectionStyleValueForProperty } from "@lexical/selection"; import katex from "katex"; import { registerMarkdownShortcuts, TRANSFORMERS, CHECK_LIST, ELEMENT_TRANSFORMERS, MULTILINE_ELEMENT_TRANSFORMERS, TEXT_FORMAT_TRANSFORMERS, TEXT_MATCH_TRANSFORMERS, $convertToMarkdownString, $convertFromMarkdownString } from "@lexical/markdown"; import { registerLexicalTextEntity, $canShowPlaceholderCurry } from "@lexical/text"; import { flushSync, createPortal } from "react-dom"; import * as SeparatorPrimitive from "@radix-ui/react-separator"; import { QuoteIcon, CodeIcon, ListTodoIcon, ListIcon, ListOrderedIcon, Heading3Icon, Heading2Icon, Heading1Icon, TextIcon, PlusIcon, ChevronRightIcon, ChevronDownIcon, CheckIcon, ChevronUpIcon, Columns3Icon, TwitterIcon, YoutubeIcon, FigmaIcon, ScissorsIcon, ImageIcon, FileImageIcon, SquareSplitVerticalIcon, ListChecksIcon, TableIcon, PaintBucketIcon, TypeIcon, CircleCheckIcon, CopyIcon, Plus, GripVerticalIcon, X, Check, Pencil, Trash, SubscriptIcon, SuperscriptIcon, CircleUserRoundIcon, AlignJustifyIcon, AlignRightIcon, AlignCenterIcon, AlignLeftIcon, MinusIcon, DiffIcon, ListCollapseIcon } from "lucide-react"; import * as SelectPrimitive from "@radix-ui/react-select"; import { cva } from "class-variance-authority"; import { Slot } from "@radix-ui/react-slot"; import * as DialogPrimitive from "@radix-ui/react-dialog"; import { DialogTrigger } from "@radix-ui/react-dialog"; import * as PopoverPrimitive from "@radix-ui/react-popover"; import { PopoverPortal } from "@radix-ui/react-popover"; import { Command as Command$1 } from "cmdk"; import * as LabelPrimitive from "@radix-ui/react-label"; import * as TabsPrimitive from "@radix-ui/react-tabs"; import * as CheckboxPrimitive from "@radix-ui/react-checkbox"; import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"; import "@radix-ui/react-toggle"; import { HexColorPicker } from "react-colorful"; import { debounce as debounce$1 } from "lodash-es"; import { ErrorBoundary } from "react-error-boundary"; const r$2 = createContext(null); function t$1(n2, e2) { let r2 = null; return null != n2 && (r2 = n2[1]), { getTheme: function() { return null != e2 ? e2 : null != r2 ? r2.getTheme() : null; } }; } function o$3() { const n2 = useContext(r$2); return null == n2 && function(n3, ...e2) { const r2 = new URL("https://lexical.dev/docs/error"), t2 = new URLSearchParams(); t2.append("code", n3); for (const n4 of e2) t2.append("v", n4); throw r2.search = t2.toString(), Error(`Minified Lexical error #${n3}; visit ${r2.toString()} for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`); }(8), n2; } const s$1 = "undefined" != typeof window && void 0 !== window.document && void 0 !== window.document.createElement, m$3 = s$1 ? useLayoutEffect : useEffect, u$2 = { tag: "history-merge" }; function p$4({ initialConfig: a2, children: c2 }) { const p2 = useMemo(() => { const { theme: t2, namespace: c3, nodes: l2, onError: d2, editorState: m2, html: p3 } = a2, f3 = t$1(null, t2), E3 = createEditor({ editable: a2.editable, html: p3, namespace: c3, nodes: l2, onError: (e2) => d2(e2, E3), theme: t2 }); return function(e2, t3) { if (null === t3) return; if (void 0 === t3) e2.update(() => { const t4 = $getRoot(); if (t4.isEmpty()) { const o2 = $createParagraphNode(); t4.append(o2); const n2 = s$1 ? document.activeElement : null; (null !== $getSelection() || null !== n2 && n2 === e2.getRootElement()) && o2.select(); } }, u$2); else if (null !== t3) switch (typeof t3) { case "string": { const o2 = e2.parseEditorState(t3); e2.setEditorState(o2, u$2); break; } case "object": e2.setEditorState(t3, u$2); break; case "function": e2.update(() => { $getRoot().isEmpty() && t3(e2); }, u$2); } }(E3, m2), [E3, f3]; }, []); return m$3(() => { const e2 = a2.editable, [t2] = p2; t2.setEditable(void 0 === e2 || e2); }, []), jsx(r$2.Provider, { value: p2, children: c2 }); } const r$1 = "undefined" != typeof window && void 0 !== window.document && void 0 !== window.document.createElement ? useLayoutEffect : useEffect; function i$3({ ignoreHistoryMergeTagChange: t2 = true, ignoreSelectionChange: o2 = false, onChange: i2 }) { const [n2] = o$3(); return r$1(() => { if (i2) return n2.registerUpdateListener(({ editorState: e2, dirtyElements: r2, dirtyLeaves: a2, prevEditorState: d2, tags: s2 }) => { o2 && 0 === r2.size && 0 === a2.size || t2 && s2.has("history-merge") || d2.isEmpty() || i2(e2, n2, s2); }); }, [n2, t2, o2, i2]), null; } const Context$2 = createContext({ isLinkEditMode: false, setIsLinkEditMode: () => { } }); function FloatingLinkContext({ children }) { const [isLinkEditMode, setIsLinkEditMode] = useState(false); return /* @__PURE__ */ jsx(Context$2.Provider, { value: { isLinkEditMode, setIsLinkEditMode }, children }); } function useFloatingLinkContext() { if (!Context$2) { throw new Error( "useFloatingLinkContext must be used within a FloatingLinkContext" ); } return useContext(Context$2); } const Context$1 = createContext([ (_cb) => () => { return; }, (_newSuggestion) => { return; } ]); function SharedAutocompleteContext({ children }) { const context = useMemo(() => { let suggestion = null; const listeners = /* @__PURE__ */ new Set(); return [ (cb) => { cb(suggestion); listeners.add(cb); return () => { listeners.delete(cb); }; }, (newSuggestion) => { suggestion = newSuggestion; for (const listener of Array.from(listeners)) { listener(newSuggestion); } } ]; }, []); return /* @__PURE__ */ jsx(Context$1.Provider, { value: context, children }); } const useSharedAutocompleteContext = () => { const [subscribe, publish] = useContext(Context$1); const [suggestion, setSuggestion] = useState(null); useEffect(() => { return subscribe((newSuggestion) => { setSuggestion(newSuggestion); }); }, [subscribe]); return [suggestion, publish]; }; const editorTheme = { ltr: "text-left", rtl: "text-right", heading: { h1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl", h2: "scroll-m-20 border-b pb-2 text-3xl font-semibold tracking-tight first:mt-0", h3: "scroll-m-20 text-2xl font-semibold tracking-tight", h4: "scroll-m-20 text-xl font-semibold tracking-tight", h5: "scroll-m-20 text-lg font-semibold tracking-tight", h6: "scroll-m-20 text-base font-semibold tracking-tight" }, paragraph: "leading-7 [&:not(:first-child)]:mt-6", quote: "mt-6 border-l-2 pl-6 italic", link: "text-content-presentation-action-link-primary hover:underline hover:cursor-pointer", list: { checklist: "relative", listitem: "mx-8", listitemChecked: 'relative mx-2 px-6 list-none outline-none line-through before:content-[""] before:w-4 before:h-4 before:top-0.5 before:left-0 before:cursor-pointer before:block before:bg-cover before:absolute before:border before:border-border-presentation-action-primary before:rounded before:bg-background-presentation-action-primary before:bg-no-repeat after:content-[""] after:cursor-pointer after:border-white after:border-solid after:absolute after:block after:top-[6px] after:w-[3px] after:left-[7px] after:right-[7px] after:h-[6px] after:rotate-45 after:border-r-2 after:border-b-2 after:border-l-0 after:border-t-0', listitemUnchecked: 'relative mx-2 px-6 list-none outline-none before:content-[""] before:w-4 before:h-4 before:top-0.5 before:left-0 before:cursor-pointer before:block before:bg-cover before:absolute before:border before:border-border-presentation-action-primary before:rounded', nested: { listitem: "list-none before:hidden after:hidden" }, ol: "my-6 ml-6 list-decimal [&>li]:mt-2", olDepth: [ "list-outside !list-decimal", "list-outside !list-[upper-roman]", "list-outside !list-[lower-roman]", "list-outside !list-[upper-alpha]", "list-outside !list-[lower-alpha]" ], ul: "m-0 p-0 list-outside" }, hashtag: "text-content-presentation-badge-blue bg-background-presentation-badge-blue rounded-md px-1", text: { bold: "font-bold", code: "bg-background-presentation-form-base p-1 rounded-md", italic: "italic", strikethrough: "line-through", subscript: "sub", superscript: "sup", underline: "underline", underlineStrikethrough: "underline line-through" }, image: "relative inline-block user-select-none cursor-default editor-image", inlineImage: "relative inline-block user-select-none cursor-default inline-editor-image", keyword: "text-content-presentation-badge-purple font-bold", code: "font-mono text-sm block p-2 my-2 overflow-x-auto border border-border-system-global-secondary rounded-lg tab-size-2 relative", codeHighlight: { atrule: "text-content-presentation-badge-purple", attr: "text-content-presentation-badge-purple", boolean: "text-content-presentation-badge-red", builtin: "text-content-presentation-badge-green", cdata: "text-content-system-global-secondary", char: "text-content-presentation-badge-green", class: "text-content-presentation-badge-rose", "class-name": "text-content-presentation-badge-rose", comment: "text-content-system-global-secondary", constant: "text-content-presentation-badge-red", deleted: "text-content-presentation-badge-red", doctype: "text-content-system-global-secondary", entity: "text-content-presentation-badge-orange", function: "text-content-presentation-badge-rose", important: "text-content-presentation-badge-yellow", inserted: "text-content-presentation-badge-green", keyword: "text-content-presentation-badge-purple", namespace: "text-content-presentation-badge-yellow", number: "text-content-presentation-badge-red", operator: "text-content-presentation-badge-orange", prolog: "text-content-system-global-secondary", property: "text-content-presentation-badge-red", punctuation: "text-content-system-global-secondary/70", regex: "text-content-presentation-badge-yellow", selector: "text-content-presentation-badge-green", string: "text-content-presentation-badge-green", symbol: "text-content-presentation-badge-red", tag: "text-content-presentation-badge-red", url: "text-content-presentation-badge-orange", variable: "text-content-presentation-badge-yellow" }, characterLimit: "!bg-background-presentation-state-negative-primary/50", table: "EditorTheme__table w-fit overflow-scroll border-collapse", tableCell: "EditorTheme__tableCell w-24 relative border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right", tableCellActionButton: "EditorTheme__tableCellActionButton bg-background-system-body-primary block border-0 rounded-2xl w-5 h-5 text-content-system-global-primary cursor-pointer", tableCellActionButtonContainer: "EditorTheme__tableCellActionButtonContainer block right-1 top-1.5 absolute z-10 w-5 h-5", tableCellEditing: "EditorTheme__tableCellEditing rounded-sm shadow-sm", tableCellHeader: "EditorTheme__tableCellHeader bg-background-system-body-secondary border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right", tableCellPrimarySelected: "EditorTheme__tableCellPrimarySelected border border-border-presentation-action-primary border-solid block h-[calc(100%-2px)] w-[calc(100%-2px)] absolute -left-[1px] -top-[1px] z-10 ", tableCellResizer: "EditorTheme__tableCellResizer absolute -right-1 h-full w-2 cursor-ew-resize z-10 top-0", tableCellSelected: "EditorTheme__tableCellSelected bg-background-system-body-secondary", tableCellSortedIndicator: "EditorTheme__tableCellSortedIndicator block opacity-50 absolute bottom-0 left-0 w-full h-1 bg-background-system-body-secondary", tableResizeRuler: "EditorTheme__tableCellResizeRuler block absolute w-[1px] h-full bg-background-presentation-action-primary top-0", tableRowStriping: "EditorTheme__tableRowStriping m-0 border-t p-0 even:bg-background-system-body-secondary", tableSelected: "EditorTheme__tableSelected ring-2 ring-border-presentation-state-focus ring-offset-2", tableSelection: "EditorTheme__tableSelection bg-transparent", layoutItem: "border border-dashed px-4 py-2", layoutContainer: "grid gap-2.5 my-2.5 mx-0", autocomplete: "text-content-system-global-secondary", blockCursor: "", embedBlock: { base: "user-select-none", focus: "ring-2 ring-border-presentation-state-focus ring-offset-2" }, hr: 'p-0.5 border-none my-1 mx-0 cursor-pointer after:content-[""] after:block after:h-0.5 after:bg-background-system-body-secondary selected:ring-2 selected:ring-border-presentation-state-focus selected:ring-offset-2 selected:user-select-none', indent: "[--lexical-indent-base-value:40px]", mark: "", markOverlap: "" }; function cn$1(...inputs) { return twMerge(clsx(inputs)); } function TooltipProvider$1({ delayDuration = 0, ...props }) { return /* @__PURE__ */ jsx( TooltipPrimitive.Provider, { "data-slot": "tooltip-provider", delayDuration, ...props } ); } function d$1(e2, t2) { return e2.getEditorState().read(() => { const e3 = $getNodeByKey(t2); return null !== e3 && e3.isSelected(); }); } function u$1(c2) { const [u2] = o$3(), [p2, s2] = useState(() => d$1(u2, c2)); useEffect(() => { let e2 = true; const t2 = u2.registerUpdateListener(() => { e2 && s2(d$1(u2, c2)); }); return () => { e2 = false, t2(); }; }, [u2, c2]); return [p2, useCallback((e2) => { u2.update(() => { let a2 = $getSelection(); $isNodeSelection(a2) || (a2 = $createNodeSelection(), $setSelection(a2)), $isNodeSelection(a2) && (e2 ? a2.add(c2) : a2.delete(c2)); }); }, [u2, c2]), useCallback(() => { u2.update(() => { const e2 = $getSelection(); $isNodeSelection(e2) && e2.clear(); }); }, [u2])]; } const p$3 = createCommand("INSERT_HORIZONTAL_RULE_COMMAND"); function d({ nodeKey: c2 }) { const [i2] = o$3(), [u2, s2, p2] = u$1(c2); return useEffect(() => mergeRegister(i2.registerCommand(CLICK_COMMAND, (e2) => { const t2 = i2.getElementByKey(c2); return e2.target === t2 && (e2.shiftKey || p2(), s2(!u2), true); }, COMMAND_PRIORITY_LOW$1)), [p2, i2, u2, c2, s2]), useEffect(() => { const e2 = i2.getElementByKey(c2), t2 = i2._config.theme.hrSelected ?? "selected"; null !== e2 && (u2 ? addClassNamesToElement(e2, t2) : removeClassNamesFromElement(e2, t2)); }, [i2, u2, c2]), null; } let f$3 = class f extends DecoratorNode { static getType() { return "horizontalrule"; } static clone(e2) { return new f(e2.__key); } static importJSON(e2) { return y$2().updateFromJSON(e2); } static importDOM() { return { hr: () => ({ conversion: x$6, priority: 0 }) }; } exportDOM() { return { element: document.createElement("hr") }; } createDOM(e2) { const t2 = document.createElement("hr"); return addClassNamesToElement(t2, e2.theme.hr), t2; } getTextContent() { return "\n"; } isInline() { return false; } updateDOM() { return false; } decorate() { return jsx(d, { nodeKey: this.__key }); } }; function x$6() { return { node: y$2() }; } function y$2() { return $applyNodeReplacement(new f$3()); } function h$3(e2) { return e2 instanceof f$3; } const elements = /* @__PURE__ */ new WeakMap(); function readTouch(e2) { const touch = e2.changedTouches[0]; if (touch === void 0) { return null; } return [touch.clientX, touch.clientY]; } function addListener(element, cb) { let elementValues = elements.get(element); if (elementValues === void 0) { const listeners = /* @__PURE__ */ new Set(); const handleTouchstart = (e2) => { if (elementValues !== void 0) { elementValues.start = readTouch(e2); } }; const handleTouchend = (e2) => { if (elementValues === void 0) { return; } const start = elementValues.start; if (start === null) { return; } const end = readTouch(e2); for (const listener of Array.from(listeners)) { if (end !== null) { listener([end[0] - start[0], end[1] - start[1]], e2); } } }; element.addEventListener("touchstart", handleTouchstart); element.addEventListener("touchend", handleTouchend); elementValues = { handleTouchend, handleTouchstart, listeners, start: null }; elements.set(element, elementValues); } elementValues.listeners.add(cb); return () => deleteListener(element, cb); } function deleteListener(element, cb) { const elementValues = elements.get(element); if (elementValues === void 0) { return; } const listeners = elementValues.listeners; listeners.delete(cb); if (listeners.size === 0) { elements.delete(element); element.removeEventListener("touchstart", elementValues.handleTouchstart); element.removeEventListener("touchend", elementValues.handleTouchend); } } function addSwipeRightListener(element, cb) { return addListener(element, (force, e2) => { const [x2, y2] = force; if (x2 > 0 && x2 > Math.abs(y2)) { cb(x2, e2); } }); } const uuid = Math.random().toString(36).replace(/[^a-z]+/g, "").substr(0, 5); function $search(selection) { if (!$isRangeSelection(selection) || !selection.isCollapsed()) { return [false, ""]; } const node = selection.getNodes()[0]; const anchor = selection.anchor; if (!$isTextNode(node) || !node.isSimpleText() || !$isAtNodeEnd(anchor)) { return [false, ""]; } const word = []; const text = node.getTextContent(); let i2 = node.getTextContentSize(); let c2; while (i2-- && i2 >= 0 && (c2 = text[i2]) !== " ") { word.push(c2); } if (word.length === 0) { return [false, ""]; } return [true, word.reverse().join("")]; } function useQuery() { return useCallback((searchText) => { const server = new AutocompleteServer(); console.time("query"); const response = server.query(searchText); console.timeEnd("query"); return response; }, []); } function AutocompletePlugin() { const [editor] = o$3(); const [, setSuggestion] = useSharedAutocompleteContext(); const query = useQuery(); useEffect(() => { let autocompleteNodeKey = null; let lastMatch = null; let lastSuggestion = null; let searchPromise = null; function $clearSuggestion() { const autocompleteNode = autocompleteNodeKey !== null ? $getNodeByKey(autocompleteNodeKey) : null; if (autocompleteNode !== null && autocompleteNode.isAttached()) { autocompleteNode.remove(); autocompleteNodeKey = null; } if (searchPromise !== null) { searchPromise.dismiss(); searchPromise = null; } lastMatch = null; lastSuggestion = null; setSuggestion(null); } function updateAsyncSuggestion(refSearchPromise, newSuggestion) { if (searchPromise !== refSearchPromise || newSuggestion === null) { return; } editor.update( () => { const selection = $getSelection(); const [hasMatch, match] = $search(selection); if (!hasMatch || match !== lastMatch || !$isRangeSelection(selection)) { return; } const selectionCopy = selection.clone(); const node = $createAutocompleteNode(uuid); autocompleteNodeKey = node.getKey(); selection.insertNodes([node]); $setSelection(selectionCopy); lastSuggestion = newSuggestion; setSuggestion(newSuggestion); }, { tag: "history-merge" } ); } function $handleAutocompleteNodeTransform(node) { const key = node.getKey(); if (node.__uuid === uuid && key !== autocompleteNodeKey) { $clearSuggestion(); } } function handleUpdate() { editor.update(() => { const selection = $getSelection(); const [hasMatch, match] = $search(selection); if (!hasMatch) { $clearSuggestion(); return; } if (match === lastMatch) { return; } $clearSuggestion(); searchPromise = query(match); searchPromise.promise.then((newSuggestion) => { if (searchPromise !== null) { updateAsyncSuggestion(searchPromise, newSuggestion); } }).catch(() => { }); lastMatch = match; }); } function $handleAutocompleteIntent() { if (lastSuggestion === null || autocompleteNodeKey === null) { return false; } const autocompleteNode = $getNodeByKey(autocompleteNodeKey); if (autocompleteNode === null) { return false; } const textNode = $createTextNode(lastSuggestion); autocompleteNode.replace(textNode); textNode.selectNext(); $clearSuggestion(); return true; } function $handleKeypressCommand(e2) { if ($handleAutocompleteIntent()) { e2.preventDefault(); return true; } return false; } function handleSwipeRight(_force, e2) { editor.update(() => { if ($handleAutocompleteIntent()) { e2.preventDefault(); } }); } function unmountSuggestion() { editor.update(() => { $clearSuggestion(); }); } const rootElem = editor.getRootElement(); return mergeRegister( editor.registerNodeTransform( AutocompleteNode, $handleAutocompleteNodeTransform ), editor.registerUpdateListener(handleUpdate), editor.registerCommand( KEY_TAB_COMMAND, $handleKeypressCommand, COMMAND_PRIORITY_LOW$1 ), editor.registerCommand( KEY_ARROW_RIGHT_COMMAND, $handleKeypressCommand, COMMAND_PRIORITY_LOW$1 ), ...rootElem !== null ? [addSwipeRightListener(rootElem, handleSwipeRight)] : [], unmountSuggestion ); }, [editor, query, setSuggestion]); return null; } class AutocompleteServer { constructor() { __publicField(this, "DATABASE", DICTIONARY); __publicField(this, "LATENCY", 200); __publicField(this, "query", (searchText) => { let isDismissed = false; const dismiss = () => { isDismissed = true; }; const promise = new Promise((resolve, reject) => { setTimeout(() => { if (isDismissed) { return reject("Dismissed"); } const searchTextLength = searchText.length; if (searchText === "" || searchTextLength < 4) { return resolve(null); } const char0 = searchText.charCodeAt(0); const isCapitalized = char0 >= 65 && char0 <= 90; const caseInsensitiveSearchText = isCapitalized ? String.fromCharCode(char0 + 32) + searchText.substring(1) : searchText; const match = this.DATABASE.find( (dictionaryWord) => dictionaryWord.startsWith(caseInsensitiveSearchText) ?? null ); if (match === void 0) { return resolve(null); } const matchCapitalized = isCapitalized ? String.fromCharCode(match.charCodeAt(0) - 32) + match.substring(1) : match; const autocompleteChunk = matchCapitalized.substring(searchTextLength); if (autocompleteChunk === "") { return resolve(null); } return resolve(autocompleteChunk); }, this.LATENCY); }); return { dismiss, promise }; }); } } const DICTIONARY = [ "information", "available", "copyright", "university", "management", "international", "development", "education", "community", "technology", "following", "resources", "including", "directory", "government", "department", "description", "insurance", "different", "categories", "conditions", "accessories", "september", "questions", "application", "financial", "equipment", "performance", "experience", "important", "activities", "additional", "something", "professional", "committee", "washington", "california", "reference", "companies", "computers", "president", "australia", "discussion", "entertainment", "agreement", "marketing", "association", "collection", "solutions", "electronics", "technical", "microsoft", "conference", "environment", "statement", "downloads", "applications", "requirements", "individual", "subscribe", "everything", "production", "commercial", "advertising", "treatment", "newsletter", "knowledge", "currently", "construction", "registered", "protection", "engineering", "published", "corporate", "customers", "materials", "countries", "standards", "political", "advertise", "environmental", "availability", "employment", "commission", "administration", "institute", "sponsored", "electronic", "condition", "effective", "organization", "selection", "corporation", "executive", "necessary", "according", "particular", "facilities", "opportunities", "appropriate", "statistics", "investment", "christmas", "registration", "furniture", "wednesday", "structure", "distribution", "industrial", "potential", "responsible", "communications", "associated", "foundation", "documents", "communication", "independent", "operating", "developed", "telephone", "population", "navigation", "operations", "therefore", "christian", "understand", "publications", "worldwide", "connection", "publisher", "introduction", "properties", "accommodation", "excellent", "opportunity", "assessment", "especially", "interface", "operation", "restaurants", "beautiful", "locations", "significant", "technologies", "manufacturer", "providing", "authority", "considered", "programme", "enterprise", "educational", "employees", "alternative", "processing", "responsibility", "resolution", "publication", "relations", "photography", "components", "assistance", "completed", "organizations", "otherwise", "transportation", "disclaimer", "membership", "recommended", "background", "character", "maintenance", "functions", "trademarks", "phentermine", "submitted", "television", "interested", "throughout", "established", "programming", "regarding", "instructions", "increased", "understanding", "beginning", "associates", "instruments", "businesses", "specified", "restaurant", "procedures", "relationship", "traditional", "sometimes", "themselves", "transport", "interesting", "evaluation", "implementation", "galleries", "references", "presented", "literature", "respective", "definition", "secretary", "networking", "australian", "magazines", "francisco", "individuals", "guidelines", "installation", "described", "attention", "difference", "regulations", "certificate", "directions", "documentation", "automotive", "successful", "communities", "situation", "publishing", "emergency", "developing", "determine", "temperature", "announcements", "historical", "ringtones", "difficult", "scientific", "satellite", "particularly", "functional", "monitoring", "architecture", "recommend", "dictionary", "accounting", "manufacturing", "professor", "generally", "continued", "techniques", "permission", "generation", "component", "guarantee", "processes", "interests", "paperback", "classifieds", "supported", "competition", "providers", "characters", "thousands", "apartments", "generated", "administrative", "practices", "reporting", "essential", "affiliate", "immediately", "designated", "integrated", "configuration", "comprehensive", "universal", "presentation", "languages", "compliance", "improvement", "pennsylvania", "challenge", "acceptance", "strategies", "affiliates", "multimedia", "certified", "computing", "interactive", "procedure", "leadership", "religious", "breakfast", "developer", "approximately", "recommendations", "comparison", "automatically", "minnesota", "adventure", "institutions", "assistant", "advertisement", "headlines", "yesterday", "determined", "wholesale", "extension", "statements", "completely", "electrical", "applicable", "manufacturers", "classical", "dedicated", "direction", "basketball", "wisconsin", "personnel", "identified", "professionals", "advantage", "newsletters", "estimated", "anonymous", "miscellaneous", "integration", "interview", "framework", "installed", "massachusetts", "associate", "frequently", "discussions", "laboratory", "destination", "intelligence", "specifications", "tripadvisor", "residential", "decisions", "industries", "partnership", "editorial", "expression", "provisions", "principles", "suggestions", "replacement", "strategic", "economics", "compatible", "apartment", "netherlands", "consulting", "recreation", "participants", "favorites", "translation", "estimates", "protected", "philadelphia", "officials", "contained", "legislation", "parameters", "relationships", "tennessee", "representative", "frequency", "introduced", "departments", "residents", "displayed", "performed", "administrator", "addresses", "permanent", "agriculture", "constitutes", "portfolio", "practical", "delivered", "collectibles", "infrastructure", "exclusive", "originally", "utilities", "philosophy", "regulation", "reduction", "nutrition", "recording", "secondary", "wonderful", "announced", "prevention", "mentioned", "automatic", "healthcare", "maintained", "increasing", "connected", "directors", "participation", "containing", "combination", "amendment", "guaranteed", "libraries", "distributed", "singapore", "enterprises", "convention", "principal", "certification", "previously", "buildings", "household", "batteries", "positions", "subscription", "contemporary", "panasonic", "permalink", "signature", "provision", "certainly", "newspaper", "liability", "trademark", "trackback", "americans", "promotion", "conversion", "reasonable", "broadband", "influence", "importance", "webmaster", "prescription", "specifically", "represent", "conservation", "louisiana", "javascript", "marketplace", "evolution", "certificates", "objectives", "suggested", "concerned", "structures", "encyclopedia", "continuing", "interracial", "competitive", "suppliers", "preparation", "receiving", "accordance", "discussed", "elizabeth", "reservations", "playstation", "instruction", "annotation", "differences", "establish", "expressed", "paragraph", "mathematics", "compensation", "conducted", "percentage", "mississippi", "requested", "connecticut", "personals", "immediate", "agricultural", "supporting", "collections", "participate", "specialist", "experienced", "investigation", "institution", "searching", "proceedings", "transmission", "characteristics", "experiences", "extremely", "verzeichnis", "contracts", "concerning", "developers", "equivalent", "chemistry", "neighborhood", "variables", "continues", "curriculum", "psychology", "responses", "circumstances", "identification", "appliances", "elementary", "unlimited", "printable", "enforcement", "hardcover", "celebrity", "chocolate", "hampshire", "bluetooth", "controlled", "requirement", "authorities", "representatives", "pregnancy", "biography", "attractions", "transactions", "authorized", "retirement", "financing", "efficiency", "efficient", "commitment", "specialty", "interviews", "qualified", "discovery", "classified", "confidence", "lifestyle", "consistent", "clearance", "connections", "inventory", "converter", "organisation", "objective", "indicated", "securities", "volunteer", "democratic", "switzerland", "parameter", "processor", "dimensions", "contribute", "challenges", "recognition", "submission", "encourage", "regulatory", "inspection", "consumers", "territory", "transaction", "manchester", "contributions", "continuous", "resulting", "cambridge", "initiative", "execution", "disability", "increases", "contractor", "examination", "indicates", "committed", "extensive", "affordable", "candidate", "databases", "outstanding", "perspective", "messenger", "tournament", "consideration", "discounts", "catalogue", "publishers", "caribbean", "reservation", "remaining", "depending", "expansion", "purchased", "performing", "collected", "absolutely", "featuring", "implement", "scheduled", "calculator", "significantly", "temporary", "sufficient", "awareness", "vancouver", "contribution", "measurement", "constitution", "packaging", "consultation", "northwest", "classroom", "democracy", "wallpaper", "merchandise", "resistance", "baltimore", "candidates", "charlotte", "biological", "transition", "preferences", "instrument", "classification", "physician", "hollywood", "wikipedia", "spiritual", "photographs", "relatively", "satisfaction", "represents", "pittsburgh", "preferred", "intellectual", "comfortable", "interaction", "listening", "effectively", "experimental", "revolution", "consolidation", "landscape", "dependent", "mechanical", "consultants", "applicant", "cooperation", "acquisition", "implemented", "directories", "recognized", "notification", "licensing", "textbooks", "diversity", "cleveland", "investments", "accessibility", "sensitive", "templates", "completion", "universities", "technique", "contractors", "subscriptions", "calculate", "alexander", "broadcast", "converted", "anniversary", "improvements", "specification", "accessible", "accessory", "typically", "representation", "arrangements", "conferences", "uniprotkb", "consumption", "birmingham", "afternoon", "consultant", "controller", "ownership", "committees", "legislative", "researchers", "unsubscribe", "molecular", "residence", "attorneys", "operators", "sustainable", "philippines", "statistical", "innovation", "employers", "definitions", "elections", "stainless", "newspapers", "hospitals", "exception", "successfully", "indonesia", "primarily", "capabilities", "recommendation", "recruitment", "organized", "improving", "expensive", "organisations", "explained", "programmes", "expertise", "mechanism", "jewellery", "eventually", "agreements", "considering", "innovative", "conclusion", "disorders", "collaboration", "detection", "formation", "engineers", "proposals", "moderator", "tutorials", "settlement", "collectables", "fantastic", "governments", "purchasing", "appointed", "operational", "corresponding", "descriptions", "determination", "animation", "productions", "telecommunications", "instructor", "approaches", "highlights", "designers", "melbourne", "scientists", "blackjack", "argentina", "possibility", "commissioner", "dangerous", "reliability", "unfortunately", "respectively", "volunteers", "attachment", "appointment", "workshops", "hurricane", "represented", "mortgages", "responsibilities", "carefully", "productivity", "investors", "underground", "diagnosis", "principle", "vacations", "calculated", "appearance", "incorporated", "notebooks", "algorithm", "valentine", "involving", "investing", "christopher", "admission", "terrorism", "parliament", "situations", "allocated", "corrections", "structural", "municipal", "describes", "disabilities", "substance", "prohibited", "addressed", "simulation", "initiatives", "concentration", "interpretation", "bankruptcy", "optimization", "substances", "discovered", "restrictions", "participating", "exhibition", "composition", "nationwide", "definitely", "existence", "commentary", "limousines", "developments", "immigration", "destinations", "necessarily", "attribute", "apparently", "surrounding", "mountains", "popularity", "postposted", "coordinator", "obviously", "fundamental", "substantial", "progressive", "championship", "sacramento", "impossible", "depression", "testimonials", "memorabilia", "cartridge", "explanation", "cincinnati", "subsection", "electricity", "permitted", "workplace", "confirmed", "wallpapers", "infection", "eligibility", "involvement", "placement", "observations", "vbulletin", "subsequent", "motorcycle", "disclosure", "establishment", "presentations", "undergraduate", "occupation", "donations", "associations", "citysearch", "radiation", "seriously", "elsewhere", "pollution", "conservative", "guestbook", "effectiveness", "demonstrate", "atmosphere", "experiment", "purchases", "federation", "assignment", "chemicals", "everybody", "nashville", "counseling", "acceptable", "satisfied", "measurements", "milwaukee", "medication", "warehouse", "shareware", "violation", "configure", "stability", "southwest", "institutional", "expectations", "independence", "metabolism", "personally", "excellence", "somewhere", "attributes", "recognize", "screening", "thumbnail", "forgotten", "intelligent", "edinburgh", "obligation", "regardless", "restricted", "republican", "merchants", "attendance", "arguments", "amsterdam", "adventures", "announcement", "appreciate", "regularly", "mechanisms", "customize", "tradition", "indicators", "emissions", "physicians", "complaint", "experiments", "afghanistan", "scholarship", "governance", "supplements", "camcorder", "implementing", "ourselves", "conversation", "capability", "producing", "precision", "contributed", "reproduction", "ingredients", "franchise", "complaints", "promotions", "rehabilitation", "maintaining", "environments", "reception", "correctly", "consequences", "geography", "appearing", "integrity", "discrimination", "processed", "implications", "functionality", "intermediate", "emotional", "platforms", "overnight", "geographic", "preliminary", "districts", "introduce", "promotional", "chevrolet", "specialists", "generator", "suspension", "correction", "authentication", "communicate", "supplement", "showtimes", "promoting", "machinery", "bandwidth", "probability", "dimension", "schedules", "admissions", "quarterly", "illustrated", "continental", "alternate", "achievement", "limitations", "automated", "passenger", "convenient", "orientation", "childhood", "flexibility", "jurisdiction", "displaying", "encouraged", "cartridges", "declaration", "automation", "advantages", "preparing", "recipient", "extensions", "athletics", "southeast", "alternatives", "determining", "personalized", "conditioning", "partnerships", "destruction", "increasingly", "migration", "basically", "conventional", "applicants", "occupational", "adjustment", "treatments", "camcorders", "difficulty", "collective", "coalition", "enrollment", "producers", "collector", "interfaces", "advertisers", "representing", "observation", "restoration", "convenience", "returning", "opposition", "container", "defendant", "confirmation", "supervisor", "peripherals", "bestsellers", "departure", "minneapolis", "interactions", "intervention", "attraction", "modification", "customized", "understood", "assurance", "happening", "amendments", "metropolitan", "compilation", "verification", "attractive", "recordings", "jefferson", "gardening", "obligations", "orchestra", "polyphonic", "outsourcing", "adjustable", "allocation", "discipline", "demonstrated", "identifying", "alphabetical", "dispatched", "installing", "voluntary", "photographer", "messaging", "constructed", "additions", "requiring", "engagement", "refinance", "calendars", "arrangement", "conclusions", "bibliography", "compatibility", "furthermore", "cooperative", "measuring", "jacksonville", "headquarters", "transfers", "transformation", "attachments", "administrators", "personality", "facilitate", "subscriber", "priorities", "bookstore", "parenting", "incredible", "commonwealth", "pharmaceutical", "manhattan", "workforce", "organizational", "portuguese", "everywhere", "discharge", "halloween", "hazardous", "methodology", "housewares", "reputation", "resistant", "democrats", "recycling", "qualifications", "slideshow", "variation", "transferred", "photograph", "distributor", "underlying", "wrestling", "photoshop", "gathering", "projection", "mathematical", "specialized", "diagnostic", "indianapolis", "corporations", "criticism", "automobile", "confidential", "statutory", "accommodations", "northeast", "downloaded", "paintings", "injection", "yorkshire", "populations", "protective", "initially", "indicator", "eliminate", "sunglasses", "preference", "threshold", "venezuela", "exploration", "sequences", "astronomy", "translate", "announces", "compression", "establishing", "constitutional", "perfectly", "instantly", "litigation", "submissions", "broadcasting", "horizontal", "terrorist", "informational", "ecommerce", "suffering", "prospective", "ultimately", "artificial", "spectacular", "coordination", "connector", "affiliated", "activation", "naturally", "subscribers", "mitsubishi", "underwear", "potentially", "constraints", "inclusive", "dimensional", "considerable", "selecting", "processors", "pantyhose", "difficulties", "complexity", "constantly", "barcelona", "presidential", "documentary", "territories", "palestinian", "legislature", "hospitality", "procurement", "theoretical", "exercises", "surveillance", "protocols", "highlight", "substitute", "inclusion", "hopefully", "brilliant", "evaluated", "assignments", "termination", "households", "authentic", "montgomery", "architectural", "louisville", "macintosh", "movements", "amenities", "virtually", "authorization", "projector", "comparative", "psychological", "surprised", "genealogy", "expenditure", "liverpool", "connectivity", "algorithms", "similarly", "collaborative", "excluding", "commander", "suggestion", "spotlight", "investigate", "connecting", "logistics", "proportion", "significance", "symposium", "essentials", "protecting", "transmitted", "screenshots", "intensive", "switching", "correspondence", "supervision", "expenditures", "separation", "testimony", "celebrities", "mandatory", "boundaries", "syndication", "celebration", "filtering", "luxembourg", "offensive", "deployment", "colleagues", "separated", "directive", "governing", "retailers", "occasionally", "attending", "recruiting", "instructional", "traveling", "permissions", "biotechnology", "prescribed", "catherine", "reproduced", "calculation", "consolidated", "occasions", "equations", "exceptional", "respondents", "considerations", "queensland", "musicians", "composite", "unavailable", "essentially", "designing", "assessments", "brunswick", "sensitivity", "preservation", "streaming", "intensity", "technological", "syndicate", "antivirus", "addressing", "discounted", "bangladesh", "constitute", "concluded", "desperate", "demonstration", "governmental", "manufactured", "graduation", "variations", "addiction", "springfield", "synthesis", "undefined", "unemployment", "enhancement", "newcastle", "performances", "societies", "brazilian", "identical", "petroleum", "norwegian", "retention", "exchanges", "soundtrack", "wondering", "profession", "separately", "physiology", "collecting", "participant", "scholarships", "recreational", "dominican", "friendship", "expanding", "provincial", "investigations", "medications", "rochester", "advertiser", "encryption", "downloadable", "sophisticated", "possession", "laboratories", "vegetables", "thumbnails", "st