text-editor-studio-ts
Version:
A powerful mobile-responsive rich text editor built with Lexical and React
1,983 lines • 814 kB
JavaScript
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