ct-rich-text-editor 1.2.9 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/style.css +440 -193
- package/dist/{babel-d155920e.js → babel-d3085146.js} +3565 -3292
- package/dist/babel-d3085146.js.map +1 -0
- package/dist/components/CodeActionMenuPlugin/utils.d.ts +1 -1
- package/dist/{estree-b1fff53b.js → estree-164983f6.js} +1763 -1778
- package/dist/estree-164983f6.js.map +1 -0
- package/dist/hooks/useDebounce.d.ts +1 -1
- package/dist/{html-f95ee5dc.js → html-5586dbf6.js} +701 -656
- package/dist/html-5586dbf6.js.map +1 -0
- package/dist/{html2pdf.bundle-583538f8.js → html2pdf.bundle-f23e1b00.js} +2 -2
- package/dist/html2pdf.bundle-f23e1b00.js.map +1 -0
- package/dist/{html2pdf.bundle.min-bc7d5952.js → html2pdf.bundle.min-daf952fb.js} +2 -2
- package/dist/html2pdf.bundle.min-daf952fb.js.map +1 -0
- package/dist/{index-91238d37.js → index-10f9d057.js} +7 -11
- package/dist/index-10f9d057.js.map +1 -0
- package/dist/{index-9d28aec6.js → index-8d147c36.js} +1243 -658
- package/dist/index-8d147c36.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{markdown-1d9e6c3f.js → markdown-d513479b.js} +1836 -1789
- package/dist/markdown-d513479b.js.map +1 -0
- package/dist/plugins/CombinedAutocompletGrammarPlugin.d.ts +22 -0
- package/dist/{postcss-c2592f3f.js → postcss-f084f74d.js} +1378 -1357
- package/dist/postcss-f084f74d.js.map +1 -0
- package/dist/standalone-5a8c6b7e.js +2518 -0
- package/dist/standalone-5a8c6b7e.js.map +1 -0
- package/dist/typescript-b1005db4.js +13705 -0
- package/dist/typescript-b1005db4.js.map +1 -0
- package/package.json +1 -1
- package/dist/babel-d155920e.js.map +0 -1
- package/dist/estree-b1fff53b.js.map +0 -1
- package/dist/html-f95ee5dc.js.map +0 -1
- package/dist/html2pdf.bundle-583538f8.js.map +0 -1
- package/dist/html2pdf.bundle.min-bc7d5952.js.map +0 -1
- package/dist/index-91238d37.js.map +0 -1
- package/dist/index-9d28aec6.js.map +0 -1
- package/dist/markdown-1d9e6c3f.js.map +0 -1
- package/dist/postcss-c2592f3f.js.map +0 -1
- package/dist/standalone-bcc7f37a.js +0 -2649
- package/dist/standalone-bcc7f37a.js.map +0 -1
- package/dist/typescript-48c10f50.js +0 -13601
- package/dist/typescript-48c10f50.js.map +0 -1
|
@@ -21,17 +21,17 @@ import { ListPlugin } from "@lexical/react/LexicalListPlugin";
|
|
|
21
21
|
import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
|
|
22
22
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
23
23
|
import { TablePlugin } from "@lexical/react/LexicalTablePlugin";
|
|
24
|
-
import { $findMatchingParent, $getNearestNodeOfType, mergeRegister, $getNearestBlockElementAncestorOrThrow, $insertNodeToNearestRoot, $wrapNodeInElement, $isEditorIsNestedEditor, calculateZoomLevel, CAN_USE_DOM } from "@lexical/utils";
|
|
24
|
+
import { $findMatchingParent, $getNearestNodeOfType, mergeRegister, $getNearestBlockElementAncestorOrThrow, $insertNodeToNearestRoot, $wrapNodeInElement, $isEditorIsNestedEditor, mediaFileReader, isMimeType, calculateZoomLevel, CAN_USE_DOM } from "@lexical/utils";
|
|
25
25
|
import Stack from "@mui/material/Stack";
|
|
26
|
-
import { createCommand, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $insertNodes, $getNearestNodeFromDOMNode, $setSelection, isHTMLElement as isHTMLElement$1, TextNode, $applyNodeReplacement, $getRoot, $createTextNode, $getNodeByKey, DecoratorNode, createEditor, COMMAND_PRIORITY_EDITOR, $createParagraphNode, $isRootOrShadowRoot, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, UNDO_COMMAND, REDO_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, CLICK_COMMAND, getDOMSelection, COMMAND_PRIORITY_HIGH, $isLineBreakNode, isDOMNode } from "lexical";
|
|
26
|
+
import { createCommand, COMMAND_PRIORITY_LOW, $getSelection, $isRangeSelection, $insertNodes, $getNearestNodeFromDOMNode, $setSelection, isHTMLElement as isHTMLElement$1, TextNode, $applyNodeReplacement, $getRoot, $createTextNode, $getNodeByKey, DecoratorNode, createEditor, COMMAND_PRIORITY_EDITOR, $createParagraphNode, $isRootOrShadowRoot, $isParagraphNode, $isTextNode, FORMAT_TEXT_COMMAND, FORMAT_ELEMENT_COMMAND, CAN_UNDO_COMMAND, CAN_REDO_COMMAND, $isElementNode, SELECTION_CHANGE_COMMAND, COMMAND_PRIORITY_CRITICAL, UNDO_COMMAND, REDO_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, KEY_ENTER_COMMAND, $createNodeSelection, $isNodeSelection, CLICK_COMMAND, getDOMSelection, COMMAND_PRIORITY_HIGH, $isLineBreakNode, PASTE_COMMAND, isDOMNode } from "lexical";
|
|
27
27
|
import * as ReactDOM from "react-dom";
|
|
28
28
|
import ReactDOM__default, { createPortal } from "react-dom";
|
|
29
29
|
import { $isCodeNode, CodeNode, normalizeCodeLang, getLanguageFriendlyName, CodeHighlightNode, CODE_LANGUAGE_MAP, $createCodeNode, registerCodeHighlighting, $isCodeHighlightNode } from "@lexical/code";
|
|
30
30
|
import { LinkNode, $isLinkNode, TOGGLE_LINK_COMMAND, $createLinkNode, $isAutoLinkNode } from "@lexical/link";
|
|
31
|
-
import { ListNode, ListItemNode, $isListNode, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND } from "@lexical/list";
|
|
32
|
-
import { HeadingNode, QuoteNode, $isHeadingNode, $createHeadingNode, $createQuoteNode } from "@lexical/rich-text";
|
|
31
|
+
import { ListNode, ListItemNode, $isListNode, INSERT_UNORDERED_LIST_COMMAND, REMOVE_LIST_COMMAND, INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, $createListNode, $createListItemNode } from "@lexical/list";
|
|
32
|
+
import { HeadingNode, QuoteNode, $isHeadingNode, $createHeadingNode, $createQuoteNode, DRAG_DROP_PASTE } from "@lexical/rich-text";
|
|
33
33
|
import { $isAtNodeEnd, $selectAll, $patchStyleText, $setBlocksType, $isParentElementRTL, $getSelectionStyleValueForProperty } from "@lexical/selection";
|
|
34
|
-
import { TableNode, TableCellNode, TableRowNode, $createTableNodeWithDimensions, TableCellHeaderStates, $isTableNode, $isTableSelection, $getTableCellNodeFromLexicalNode, $getTableNodeFromLexicalNodeOrThrow, getTableElement, getTableObserverFromTableElement, $isTableCellNode, $insertTableRow__EXPERIMENTAL, $insertTableColumn__EXPERIMENTAL, $
|
|
34
|
+
import { TableNode, TableCellNode, TableRowNode, $createTableNodeWithDimensions, TableCellHeaderStates, $isTableNode, $isTableSelection, $getTableCellNodeFromLexicalNode, $getTableNodeFromLexicalNodeOrThrow, getTableElement, getTableObserverFromTableElement, $isTableCellNode, $insertTableRow__EXPERIMENTAL, $insertTableColumn__EXPERIMENTAL, $getNodeTriplet, $isTableRowNode, $deleteTableRow__EXPERIMENTAL, $deleteTableColumn__EXPERIMENTAL, $getTableRowIndexFromTableCellNode, $getTableColumnIndexFromTableCellNode, $unmergeCell, $computeTableMapSkipCellCheck, getDOMCellFromTarget, $getTableAndElementByKey } from "@lexical/table";
|
|
35
35
|
import { HorizontalRuleNode } from "@lexical/react/LexicalHorizontalRuleNode";
|
|
36
36
|
import DescriptionIcon from "@mui/icons-material/Description";
|
|
37
37
|
import FolderZipIcon from "@mui/icons-material/FolderZip";
|
|
@@ -2699,6 +2699,17 @@ const Highlighter = createLucideIcon("Highlighter", [
|
|
|
2699
2699
|
["path", { d: "m9 11-6 6v3h9l3-3", key: "1a3l36" }],
|
|
2700
2700
|
["path", { d: "m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4", key: "14a9rk" }]
|
|
2701
2701
|
]);
|
|
2702
|
+
/**
|
|
2703
|
+
* @license lucide-react v0.344.0 - ISC
|
|
2704
|
+
*
|
|
2705
|
+
* This source code is licensed under the ISC license.
|
|
2706
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2707
|
+
*/
|
|
2708
|
+
const Image$2 = createLucideIcon("Image", [
|
|
2709
|
+
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
2710
|
+
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
2711
|
+
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
2712
|
+
]);
|
|
2702
2713
|
/**
|
|
2703
2714
|
* @license lucide-react v0.344.0 - ISC
|
|
2704
2715
|
*
|
|
@@ -2727,6 +2738,47 @@ const Lightbulb = createLucideIcon("Lightbulb", [
|
|
|
2727
2738
|
["path", { d: "M9 18h6", key: "x1upvd" }],
|
|
2728
2739
|
["path", { d: "M10 22h4", key: "ceow96" }]
|
|
2729
2740
|
]);
|
|
2741
|
+
/**
|
|
2742
|
+
* @license lucide-react v0.344.0 - ISC
|
|
2743
|
+
*
|
|
2744
|
+
* This source code is licensed under the ISC license.
|
|
2745
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2746
|
+
*/
|
|
2747
|
+
const ListChecks = createLucideIcon("ListChecks", [
|
|
2748
|
+
["path", { d: "m3 17 2 2 4-4", key: "1jhpwq" }],
|
|
2749
|
+
["path", { d: "m3 7 2 2 4-4", key: "1obspn" }],
|
|
2750
|
+
["path", { d: "M13 6h8", key: "15sg57" }],
|
|
2751
|
+
["path", { d: "M13 12h8", key: "h98zly" }],
|
|
2752
|
+
["path", { d: "M13 18h8", key: "oe0vm4" }]
|
|
2753
|
+
]);
|
|
2754
|
+
/**
|
|
2755
|
+
* @license lucide-react v0.344.0 - ISC
|
|
2756
|
+
*
|
|
2757
|
+
* This source code is licensed under the ISC license.
|
|
2758
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2759
|
+
*/
|
|
2760
|
+
const ListOrdered = createLucideIcon("ListOrdered", [
|
|
2761
|
+
["line", { x1: "10", x2: "21", y1: "6", y2: "6", key: "76qw6h" }],
|
|
2762
|
+
["line", { x1: "10", x2: "21", y1: "12", y2: "12", key: "16nom4" }],
|
|
2763
|
+
["line", { x1: "10", x2: "21", y1: "18", y2: "18", key: "u3jurt" }],
|
|
2764
|
+
["path", { d: "M4 6h1v4", key: "cnovpq" }],
|
|
2765
|
+
["path", { d: "M4 10h2", key: "16xx2s" }],
|
|
2766
|
+
["path", { d: "M6 18H4c0-1 2-2 2-3s-1-1.5-2-1", key: "m9a95d" }]
|
|
2767
|
+
]);
|
|
2768
|
+
/**
|
|
2769
|
+
* @license lucide-react v0.344.0 - ISC
|
|
2770
|
+
*
|
|
2771
|
+
* This source code is licensed under the ISC license.
|
|
2772
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2773
|
+
*/
|
|
2774
|
+
const List$1 = createLucideIcon("List", [
|
|
2775
|
+
["line", { x1: "8", x2: "21", y1: "6", y2: "6", key: "7ey8pc" }],
|
|
2776
|
+
["line", { x1: "8", x2: "21", y1: "12", y2: "12", key: "rjfblc" }],
|
|
2777
|
+
["line", { x1: "8", x2: "21", y1: "18", y2: "18", key: "c3b1m8" }],
|
|
2778
|
+
["line", { x1: "3", x2: "3.01", y1: "6", y2: "6", key: "1g7gq3" }],
|
|
2779
|
+
["line", { x1: "3", x2: "3.01", y1: "12", y2: "12", key: "1pjlvk" }],
|
|
2780
|
+
["line", { x1: "3", x2: "3.01", y1: "18", y2: "18", key: "28t2mc" }]
|
|
2781
|
+
]);
|
|
2730
2782
|
/**
|
|
2731
2783
|
* @license lucide-react v0.344.0 - ISC
|
|
2732
2784
|
*
|
|
@@ -2937,6 +2989,16 @@ const Type = createLucideIcon("Type", [
|
|
|
2937
2989
|
["line", { x1: "9", x2: "15", y1: "20", y2: "20", key: "swin9y" }],
|
|
2938
2990
|
["line", { x1: "12", x2: "12", y1: "4", y2: "20", key: "1tx1rr" }]
|
|
2939
2991
|
]);
|
|
2992
|
+
/**
|
|
2993
|
+
* @license lucide-react v0.344.0 - ISC
|
|
2994
|
+
*
|
|
2995
|
+
* This source code is licensed under the ISC license.
|
|
2996
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
2997
|
+
*/
|
|
2998
|
+
const Video = createLucideIcon("Video", [
|
|
2999
|
+
["path", { d: "m22 8-6 4 6 4V8Z", key: "50v9me" }],
|
|
3000
|
+
["rect", { width: "14", height: "12", x: "2", y: "6", rx: "2", ry: "2", key: "1rqjg6" }]
|
|
3001
|
+
]);
|
|
2940
3002
|
/**
|
|
2941
3003
|
* @license lucide-react v0.344.0 - ISC
|
|
2942
3004
|
*
|
|
@@ -7760,16 +7822,16 @@ function CopyButton({ editor, getCodeDOMNode }) {
|
|
|
7760
7822
|
}
|
|
7761
7823
|
const index$4 = "";
|
|
7762
7824
|
const PRETTIER_PARSER_MODULES = {
|
|
7763
|
-
css: [() => import("./postcss-
|
|
7764
|
-
html: [() => import("./html-
|
|
7825
|
+
css: [() => import("./postcss-f084f74d.js")],
|
|
7826
|
+
html: [() => import("./html-5586dbf6.js")],
|
|
7765
7827
|
js: [
|
|
7766
|
-
() => import("./babel-
|
|
7767
|
-
() => import("./estree-
|
|
7828
|
+
() => import("./babel-d3085146.js"),
|
|
7829
|
+
() => import("./estree-164983f6.js")
|
|
7768
7830
|
],
|
|
7769
|
-
markdown: [() => import("./markdown-
|
|
7831
|
+
markdown: [() => import("./markdown-d513479b.js")],
|
|
7770
7832
|
typescript: [
|
|
7771
|
-
() => import("./typescript-
|
|
7772
|
-
() => import("./estree-
|
|
7833
|
+
() => import("./typescript-b1005db4.js"),
|
|
7834
|
+
() => import("./estree-164983f6.js")
|
|
7773
7835
|
]
|
|
7774
7836
|
};
|
|
7775
7837
|
async function loadPrettierParserByLang(lang) {
|
|
@@ -7780,7 +7842,7 @@ async function loadPrettierParserByLang(lang) {
|
|
|
7780
7842
|
return modules;
|
|
7781
7843
|
}
|
|
7782
7844
|
async function loadPrettierFormat() {
|
|
7783
|
-
const { format } = await import("./standalone-
|
|
7845
|
+
const { format } = await import("./standalone-5a8c6b7e.js");
|
|
7784
7846
|
return format;
|
|
7785
7847
|
}
|
|
7786
7848
|
const PRETTIER_OPTIONS_BY_LANG = {
|
|
@@ -12655,10 +12717,10 @@ const PDF_CONFIG = {
|
|
|
12655
12717
|
};
|
|
12656
12718
|
const loadHtml2Pdf = async () => {
|
|
12657
12719
|
try {
|
|
12658
|
-
const mod = await import("./html2pdf.bundle.min-
|
|
12720
|
+
const mod = await import("./html2pdf.bundle.min-daf952fb.js").then((n) => n.h);
|
|
12659
12721
|
return (mod == null ? void 0 : mod.default) || mod;
|
|
12660
12722
|
} catch {
|
|
12661
|
-
const mod2 = await import("./html2pdf.bundle-
|
|
12723
|
+
const mod2 = await import("./html2pdf.bundle-f23e1b00.js").then((n) => n.h);
|
|
12662
12724
|
return (mod2 == null ? void 0 : mod2.default) || mod2;
|
|
12663
12725
|
}
|
|
12664
12726
|
};
|
|
@@ -13865,7 +13927,7 @@ const EmbedComponent = ({ url, displayType, alignment, nodeKey }) => {
|
|
|
13865
13927
|
}
|
|
13866
13928
|
);
|
|
13867
13929
|
};
|
|
13868
|
-
const ImageView = React__default.lazy(() => import("./index-
|
|
13930
|
+
const ImageView = React__default.lazy(() => import("./index-10f9d057.js"));
|
|
13869
13931
|
function isGoogleDocCheckboxImg(img) {
|
|
13870
13932
|
return img.parentElement != null && img.parentElement.tagName === "LI" && img.previousSibling === null && img.getAttribute("aria-roledescription") === "checkbox";
|
|
13871
13933
|
}
|
|
@@ -16395,6 +16457,7 @@ function TableOptionPlugin() {
|
|
|
16395
16457
|
htmlCell.style.setProperty("padding", "8px", "important");
|
|
16396
16458
|
htmlCell.style.setProperty("border", "1px solid #ddd", "important");
|
|
16397
16459
|
htmlCell.style.setProperty("font-weight", "bold", "important");
|
|
16460
|
+
htmlCell.style.setProperty("white-space", "nowrap", "important");
|
|
16398
16461
|
}
|
|
16399
16462
|
});
|
|
16400
16463
|
}
|
|
@@ -16442,6 +16505,7 @@ function TableOptionPlugin() {
|
|
|
16442
16505
|
for (let i2 = 0; i2 < cells.length; i2++) {
|
|
16443
16506
|
const headingText = (columnHeadings[i2] || "").trim();
|
|
16444
16507
|
const cellNode = cells[i2];
|
|
16508
|
+
cellNode.clear();
|
|
16445
16509
|
if (headingText) {
|
|
16446
16510
|
cellNode.append($createTextNode(headingText));
|
|
16447
16511
|
}
|
|
@@ -16474,6 +16538,7 @@ function TableOptionPlugin() {
|
|
|
16474
16538
|
htmlCell.style.setProperty("padding", "8px", "important");
|
|
16475
16539
|
htmlCell.style.setProperty("border", "1px solid #ddd", "important");
|
|
16476
16540
|
htmlCell.style.setProperty("font-weight", "bold", "important");
|
|
16541
|
+
htmlCell.style.setProperty("white-space", "nowrap", "important");
|
|
16477
16542
|
});
|
|
16478
16543
|
return true;
|
|
16479
16544
|
}
|
|
@@ -21214,6 +21279,7 @@ const InsertImageUploadedDialogBody = ({
|
|
|
21214
21279
|
const { uploadFileToS3, uploadedUrl, progress, uploading } = useS3Uploader(apiKey || void 0);
|
|
21215
21280
|
const [tempSrc, setTempSrc] = useState$1("");
|
|
21216
21281
|
const [fileToUpload, setFileToUpload] = useState$1(null);
|
|
21282
|
+
const [imageDimensions, setImageDimensions] = useState$1(null);
|
|
21217
21283
|
const onChangeImage = async (event) => {
|
|
21218
21284
|
const files = event.target.files;
|
|
21219
21285
|
if (!files || files.length === 0)
|
|
@@ -21224,6 +21290,11 @@ const InsertImageUploadedDialogBody = ({
|
|
|
21224
21290
|
reader.onload = () => {
|
|
21225
21291
|
if (typeof reader.result === "string") {
|
|
21226
21292
|
setTempSrc(reader.result);
|
|
21293
|
+
const img = new Image();
|
|
21294
|
+
img.onload = () => {
|
|
21295
|
+
setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight });
|
|
21296
|
+
};
|
|
21297
|
+
img.src = reader.result;
|
|
21227
21298
|
}
|
|
21228
21299
|
};
|
|
21229
21300
|
reader.readAsDataURL(file);
|
|
@@ -21233,9 +21304,19 @@ const InsertImageUploadedDialogBody = ({
|
|
|
21233
21304
|
return;
|
|
21234
21305
|
try {
|
|
21235
21306
|
const uploadedUrl2 = await uploadFileToS3(fileToUpload);
|
|
21236
|
-
|
|
21307
|
+
console.log("Upload successful! URL:", uploadedUrl2);
|
|
21308
|
+
console.log("Image dimensions:", imageDimensions);
|
|
21309
|
+
const payload = {
|
|
21310
|
+
altText,
|
|
21311
|
+
src: uploadedUrl2,
|
|
21312
|
+
width: imageDimensions == null ? void 0 : imageDimensions.width,
|
|
21313
|
+
height: imageDimensions == null ? void 0 : imageDimensions.height
|
|
21314
|
+
};
|
|
21315
|
+
console.log("Inserting image with payload:", payload);
|
|
21316
|
+
onClick(payload);
|
|
21237
21317
|
setTempSrc("");
|
|
21238
21318
|
setFileToUpload(null);
|
|
21319
|
+
setImageDimensions(null);
|
|
21239
21320
|
} catch (error) {
|
|
21240
21321
|
console.error("Upload failed:", error);
|
|
21241
21322
|
}
|
|
@@ -21317,6 +21398,7 @@ const InsertImageUrlDialogBody = ({
|
|
|
21317
21398
|
const [altText, setAltText] = useState$1("");
|
|
21318
21399
|
const [isValidUrl, setIsValidUrl] = useState$1(false);
|
|
21319
21400
|
const [previewError, setPreviewError] = useState$1(null);
|
|
21401
|
+
const [imageDimensions, setImageDimensions] = useState$1(null);
|
|
21320
21402
|
const validateUrl2 = (url) => {
|
|
21321
21403
|
if (!url.trim())
|
|
21322
21404
|
return false;
|
|
@@ -21352,6 +21434,7 @@ const InsertImageUrlDialogBody = ({
|
|
|
21352
21434
|
img.onload = () => {
|
|
21353
21435
|
setPreviewError(null);
|
|
21354
21436
|
setIsValidUrl(true);
|
|
21437
|
+
setImageDimensions({ width: img.naturalWidth, height: img.naturalHeight });
|
|
21355
21438
|
};
|
|
21356
21439
|
img.onerror = () => {
|
|
21357
21440
|
setPreviewError(
|
|
@@ -21364,7 +21447,12 @@ const InsertImageUrlDialogBody = ({
|
|
|
21364
21447
|
const handleConfirmUrl = () => {
|
|
21365
21448
|
if (!imageUrl || !isValidUrl)
|
|
21366
21449
|
return;
|
|
21367
|
-
onClick({
|
|
21450
|
+
onClick({
|
|
21451
|
+
altText,
|
|
21452
|
+
src: imageUrl,
|
|
21453
|
+
width: imageDimensions == null ? void 0 : imageDimensions.width,
|
|
21454
|
+
height: imageDimensions == null ? void 0 : imageDimensions.height
|
|
21455
|
+
});
|
|
21368
21456
|
};
|
|
21369
21457
|
return /* @__PURE__ */ jsxs("div", { className: "cteditor-space-y-4", children: [
|
|
21370
21458
|
imageUrl && isValidUrl && !previewError && /* @__PURE__ */ jsx("div", { className: "cteditor-mb-4", children: /* @__PURE__ */ jsx(
|
|
@@ -22644,8 +22732,8 @@ const NotePanelMenu = ({ className }) => {
|
|
|
22644
22732
|
] });
|
|
22645
22733
|
};
|
|
22646
22734
|
const useStyles$1 = () => ({
|
|
22647
|
-
root: "cteditor-p-2 cteditor-border-b cteditor-border-[#e0e0e0] cteditor-overflow-auto",
|
|
22648
|
-
toolbar: "cteditor-p-2 cteditor-overflow-auto",
|
|
22735
|
+
root: "cteditor-p-2 cteditor-border-b cteditor-border-[#e0e0e0] cteditor-max-w-full cteditor-overflow-x-auto",
|
|
22736
|
+
toolbar: "cteditor-p-2 cteditor-max-w-full cteditor-overflow-x-auto cteditor-flex cteditor-flex-nowrap cteditor-gap-1",
|
|
22649
22737
|
toolbarButton: "cteditor-p-1.5"
|
|
22650
22738
|
});
|
|
22651
22739
|
const useModal$1 = () => {
|
|
@@ -22827,8 +22915,17 @@ const Toolbar = ({
|
|
|
22827
22915
|
enableHtmlView
|
|
22828
22916
|
]);
|
|
22829
22917
|
const handleClearEditorContent = () => {
|
|
22830
|
-
|
|
22831
|
-
|
|
22918
|
+
toast.warning("Clear editor content?", {
|
|
22919
|
+
description: "This will remove all content.",
|
|
22920
|
+
action: {
|
|
22921
|
+
label: "OK",
|
|
22922
|
+
onClick: () => {
|
|
22923
|
+
clearEditorContent();
|
|
22924
|
+
toast.success("Editor cleared");
|
|
22925
|
+
}
|
|
22926
|
+
},
|
|
22927
|
+
duration: 8e3
|
|
22928
|
+
});
|
|
22832
22929
|
};
|
|
22833
22930
|
const { onFontColorSelect, onBgColorSelect, onHighlightColorSelect } = useColorPicker();
|
|
22834
22931
|
const [isLinkActive, setIsLinkActive] = useState$1(false);
|
|
@@ -23149,14 +23246,17 @@ const Toolbar = ({
|
|
|
23149
23246
|
"div",
|
|
23150
23247
|
{
|
|
23151
23248
|
ref: contentRef,
|
|
23152
|
-
className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-flex-1 cteditor-overflow-x-auto cteditor-
|
|
23153
|
-
style: {
|
|
23249
|
+
className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-flex-1 cteditor-overflow-x-auto cteditor-flex-nowrap",
|
|
23250
|
+
style: {
|
|
23251
|
+
scrollBehavior: "smooth",
|
|
23252
|
+
WebkitOverflowScrolling: "touch"
|
|
23253
|
+
},
|
|
23154
23254
|
children: [
|
|
23155
23255
|
enableUndoRedo && /* @__PURE__ */ jsxs(
|
|
23156
23256
|
"div",
|
|
23157
23257
|
{
|
|
23158
23258
|
"data-toolbar-item": "undoRedo",
|
|
23159
|
-
className: "cteditor-flex cteditor-items-center cteditor-gap-1.5",
|
|
23259
|
+
className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-flex-shrink-0",
|
|
23160
23260
|
children: [
|
|
23161
23261
|
/* @__PURE__ */ jsx(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs(Tooltip, { children: [
|
|
23162
23262
|
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
|
|
@@ -24051,9 +24151,8 @@ function Skeleton({
|
|
|
24051
24151
|
}
|
|
24052
24152
|
);
|
|
24053
24153
|
}
|
|
24054
|
-
|
|
24055
|
-
|
|
24056
|
-
);
|
|
24154
|
+
const GrammarCheckPlugin = "";
|
|
24155
|
+
createCommand("AUTOCOMPLETE_COMMAND");
|
|
24057
24156
|
const STATIC_SUGGESTIONS = [
|
|
24058
24157
|
"javascript",
|
|
24059
24158
|
"typescript",
|
|
@@ -24081,7 +24180,6 @@ class AIService {
|
|
|
24081
24180
|
__publicField(this, "apiEndpoint");
|
|
24082
24181
|
__publicField(this, "cache", /* @__PURE__ */ new Map());
|
|
24083
24182
|
__publicField(this, "requestTimeout", 1e4);
|
|
24084
|
-
// 10 seconds timeout for more reliable responses
|
|
24085
24183
|
__publicField(this, "pendingRequests", /* @__PURE__ */ new Map());
|
|
24086
24184
|
this.apiEndpoint = "https://api.cteditor.com/" + apiEndpoint;
|
|
24087
24185
|
}
|
|
@@ -24103,19 +24201,9 @@ class AIService {
|
|
|
24103
24201
|
}
|
|
24104
24202
|
}
|
|
24105
24203
|
async executeRequest(payload, cacheKey) {
|
|
24106
|
-
var _a;
|
|
24107
24204
|
try {
|
|
24108
24205
|
const controller = new AbortController();
|
|
24109
|
-
const timeoutId = setTimeout(
|
|
24110
|
-
() => controller.abort(),
|
|
24111
|
-
this.requestTimeout
|
|
24112
|
-
);
|
|
24113
|
-
console.log("🌐 AIService: Making request to:", this.apiEndpoint);
|
|
24114
|
-
console.log("📦 AIService: Payload:", {
|
|
24115
|
-
...payload,
|
|
24116
|
-
text: ((_a = payload.text) == null ? void 0 : _a.substring(0, 100)) + "..."
|
|
24117
|
-
// Log only first 100 chars
|
|
24118
|
-
});
|
|
24206
|
+
const timeoutId = setTimeout(() => controller.abort(), this.requestTimeout);
|
|
24119
24207
|
const response = await fetch(this.apiEndpoint, {
|
|
24120
24208
|
method: "POST",
|
|
24121
24209
|
headers: {
|
|
@@ -24125,14 +24213,11 @@ class AIService {
|
|
|
24125
24213
|
signal: controller.signal
|
|
24126
24214
|
});
|
|
24127
24215
|
clearTimeout(timeoutId);
|
|
24128
|
-
console.log("📡 AIService: Response status:", response.status);
|
|
24129
24216
|
if (!response.ok) {
|
|
24130
24217
|
const errorText = await response.text();
|
|
24131
|
-
console.error("❌ AIService: Error response:", errorText);
|
|
24132
24218
|
throw new Error(`AI service error: ${response.status} - ${errorText}`);
|
|
24133
24219
|
}
|
|
24134
24220
|
const result = await response.json();
|
|
24135
|
-
console.log("✅ AIService: Successful response received");
|
|
24136
24221
|
this.cache.set(cacheKey, result.data);
|
|
24137
24222
|
if (this.cache.size > 50) {
|
|
24138
24223
|
const firstKey = this.cache.keys().next().value;
|
|
@@ -24142,15 +24227,7 @@ class AIService {
|
|
|
24142
24227
|
}
|
|
24143
24228
|
return result.data;
|
|
24144
24229
|
} catch (error) {
|
|
24145
|
-
|
|
24146
|
-
console.warn(
|
|
24147
|
-
"⏰ AIService: Request timed out after",
|
|
24148
|
-
this.requestTimeout,
|
|
24149
|
-
"ms"
|
|
24150
|
-
);
|
|
24151
|
-
} else {
|
|
24152
|
-
console.error("❌ AIService: Request failed:", error);
|
|
24153
|
-
}
|
|
24230
|
+
console.error("❌ AIService: Request failed:", error);
|
|
24154
24231
|
return null;
|
|
24155
24232
|
}
|
|
24156
24233
|
}
|
|
@@ -24160,43 +24237,118 @@ class AIService {
|
|
|
24160
24237
|
}
|
|
24161
24238
|
const result = await this.makeRequest({
|
|
24162
24239
|
text: text.trim(),
|
|
24163
|
-
// Send the sentence/text for correction
|
|
24164
24240
|
currentWord: currentWord == null ? void 0 : currentWord.trim(),
|
|
24165
|
-
// Send current word being typed (optional)
|
|
24166
24241
|
maxSuggestions
|
|
24167
24242
|
});
|
|
24168
24243
|
return result;
|
|
24169
24244
|
}
|
|
24170
24245
|
}
|
|
24171
|
-
|
|
24246
|
+
class GrammarCheckService {
|
|
24247
|
+
constructor() {
|
|
24248
|
+
__publicField(this, "cache", /* @__PURE__ */ new Map());
|
|
24249
|
+
__publicField(this, "apiEndpoint");
|
|
24250
|
+
__publicField(this, "pendingRequest", null);
|
|
24251
|
+
this.apiEndpoint = "https://api.cteditor.com/api/ai/process";
|
|
24252
|
+
}
|
|
24253
|
+
async check(text) {
|
|
24254
|
+
if (!text || text.trim().length < 3) {
|
|
24255
|
+
return [];
|
|
24256
|
+
}
|
|
24257
|
+
const cacheKey = text.trim();
|
|
24258
|
+
if (this.cache.has(cacheKey)) {
|
|
24259
|
+
return this.cache.get(cacheKey);
|
|
24260
|
+
}
|
|
24261
|
+
if (this.pendingRequest) {
|
|
24262
|
+
return this.pendingRequest;
|
|
24263
|
+
}
|
|
24264
|
+
this.pendingRequest = this.executeCheck(text);
|
|
24265
|
+
try {
|
|
24266
|
+
const result = await this.pendingRequest;
|
|
24267
|
+
return result;
|
|
24268
|
+
} finally {
|
|
24269
|
+
this.pendingRequest = null;
|
|
24270
|
+
}
|
|
24271
|
+
}
|
|
24272
|
+
async executeCheck(text) {
|
|
24273
|
+
var _a, _b, _c, _d, _e, _f;
|
|
24274
|
+
try {
|
|
24275
|
+
const response = await fetch(this.apiEndpoint, {
|
|
24276
|
+
method: "POST",
|
|
24277
|
+
headers: { "Content-Type": "application/json" },
|
|
24278
|
+
body: JSON.stringify({ text: text.trim(), maxSuggestions: 3 }),
|
|
24279
|
+
signal: AbortSignal.timeout(1e4)
|
|
24280
|
+
});
|
|
24281
|
+
if (!response.ok) {
|
|
24282
|
+
console.error("❌ GrammarCheck: API error:", response.status);
|
|
24283
|
+
return [];
|
|
24284
|
+
}
|
|
24285
|
+
const result = await response.json();
|
|
24286
|
+
const foundErrors = [];
|
|
24287
|
+
if ((_c = (_b = (_a = result.data) == null ? void 0 : _a.corrections) == null ? void 0 : _b.spelling) == null ? void 0 : _c.errors) {
|
|
24288
|
+
result.data.corrections.spelling.errors.forEach((err, idx) => {
|
|
24289
|
+
foundErrors.push({
|
|
24290
|
+
type: "spelling",
|
|
24291
|
+
original: err.original,
|
|
24292
|
+
suggestions: err.suggestions || [],
|
|
24293
|
+
index: idx
|
|
24294
|
+
});
|
|
24295
|
+
});
|
|
24296
|
+
}
|
|
24297
|
+
if ((_f = (_e = (_d = result.data) == null ? void 0 : _d.corrections) == null ? void 0 : _e.grammar) == null ? void 0 : _f.errors) {
|
|
24298
|
+
result.data.corrections.grammar.errors.forEach((err, idx) => {
|
|
24299
|
+
foundErrors.push({
|
|
24300
|
+
type: "grammar",
|
|
24301
|
+
original: err.original || text,
|
|
24302
|
+
suggestions: [err.suggestion],
|
|
24303
|
+
index: foundErrors.length + idx,
|
|
24304
|
+
issue: err.issue
|
|
24305
|
+
});
|
|
24306
|
+
});
|
|
24307
|
+
}
|
|
24308
|
+
this.cache.set(text.trim(), foundErrors);
|
|
24309
|
+
if (this.cache.size > 30) {
|
|
24310
|
+
const firstKey = this.cache.keys().next().value;
|
|
24311
|
+
if (firstKey) {
|
|
24312
|
+
this.cache.delete(firstKey);
|
|
24313
|
+
}
|
|
24314
|
+
}
|
|
24315
|
+
return foundErrors;
|
|
24316
|
+
} catch (error) {
|
|
24317
|
+
console.error("❌ GrammarCheck: Check failed:", error);
|
|
24318
|
+
return [];
|
|
24319
|
+
}
|
|
24320
|
+
}
|
|
24321
|
+
}
|
|
24322
|
+
function CombinedAutocompleteGrammarPlugin({
|
|
24172
24323
|
onQueryChange,
|
|
24173
24324
|
onSelectOption,
|
|
24174
24325
|
minMatchLength = 2,
|
|
24175
24326
|
maxSuggestions = 10,
|
|
24176
|
-
// anchorClassName = "",
|
|
24177
|
-
// menuClassName = "",
|
|
24178
|
-
// itemClassName = "",
|
|
24179
|
-
// selectedItemClassName = "",
|
|
24180
24327
|
apiEndpoint = "api/ai/process",
|
|
24181
24328
|
enableAI = true,
|
|
24182
24329
|
debounceDelay = 200
|
|
24183
24330
|
}) {
|
|
24184
24331
|
const [editor] = useLexicalComposerContext();
|
|
24185
24332
|
const { updateToolbarState } = useToolbarState();
|
|
24333
|
+
const [activeTab, setActiveTab] = useState$1("autocomplete");
|
|
24186
24334
|
const [queryString, setQueryString] = useState$1(null);
|
|
24187
24335
|
const [suggestions, setSuggestions] = useState$1([]);
|
|
24188
24336
|
const [selectedIndex, setSelectedIndex] = useState$1(0);
|
|
24189
24337
|
const [isLoading, setIsLoading] = useState$1(false);
|
|
24190
24338
|
const menuRef = useRef(null);
|
|
24191
24339
|
const anchorElementRef = useRef(null);
|
|
24192
|
-
const [anchorElement, setAnchorElement] = useState$1(
|
|
24193
|
-
null
|
|
24194
|
-
);
|
|
24340
|
+
const [anchorElement, setAnchorElement] = useState$1(null);
|
|
24195
24341
|
const aiService = useRef(new AIService(apiEndpoint));
|
|
24196
24342
|
const debounceTimer = useRef(null);
|
|
24197
24343
|
const justSelectedOption = useRef(false);
|
|
24198
24344
|
const lastRequestTime = useRef(0);
|
|
24199
24345
|
const requestThrottle = 100;
|
|
24346
|
+
const [errors, setErrors] = useState$1([]);
|
|
24347
|
+
const [userDismissed, setUserDismissed] = useState$1(false);
|
|
24348
|
+
const grammarService = useRef(new GrammarCheckService());
|
|
24349
|
+
const checkTimeout = useRef();
|
|
24350
|
+
const lastCheckedText = useRef("");
|
|
24351
|
+
const highlightElementsRef = useRef([]);
|
|
24200
24352
|
const extractWordsFromEditor = useCallback(() => {
|
|
24201
24353
|
const words = /* @__PURE__ */ new Set();
|
|
24202
24354
|
STATIC_SUGGESTIONS.forEach((word) => words.add(word));
|
|
@@ -24221,17 +24373,12 @@ function AutocompletePlugin({
|
|
|
24221
24373
|
return [];
|
|
24222
24374
|
}
|
|
24223
24375
|
if (justSelectedOption.current) {
|
|
24224
|
-
console.log(
|
|
24225
|
-
"🚫 AutocompletePlugin: Skipping AI request - just selected option"
|
|
24226
|
-
);
|
|
24227
24376
|
return [];
|
|
24228
24377
|
}
|
|
24229
24378
|
const now2 = Date.now();
|
|
24230
24379
|
if (now2 - lastRequestTime.current < requestThrottle) {
|
|
24231
|
-
console.log("🚫 AutocompletePlugin: Throttling AI request");
|
|
24232
24380
|
return [];
|
|
24233
24381
|
}
|
|
24234
|
-
console.log("🤖 AutocompletePlugin: Getting AI suggestions for:", query);
|
|
24235
24382
|
setIsLoading(true);
|
|
24236
24383
|
lastRequestTime.current = now2;
|
|
24237
24384
|
let lastSentence = "";
|
|
@@ -24270,11 +24417,8 @@ function AutocompletePlugin({
|
|
|
24270
24417
|
try {
|
|
24271
24418
|
const result = await aiService.current.getIntelligentSuggestions(
|
|
24272
24419
|
query,
|
|
24273
|
-
// currentWord
|
|
24274
24420
|
lastSentence,
|
|
24275
|
-
// text (the sentence to correct)
|
|
24276
24421
|
maxSuggestions
|
|
24277
|
-
// maxSuggestions
|
|
24278
24422
|
);
|
|
24279
24423
|
const aiOptions = [];
|
|
24280
24424
|
if (result) {
|
|
@@ -24347,10 +24491,6 @@ function AutocompletePlugin({
|
|
|
24347
24491
|
});
|
|
24348
24492
|
}
|
|
24349
24493
|
}
|
|
24350
|
-
console.log(
|
|
24351
|
-
"✅ AutocompletePlugin: AI sentence corrections received:",
|
|
24352
|
-
aiOptions
|
|
24353
|
-
);
|
|
24354
24494
|
return aiOptions.slice(0, Math.floor(maxSuggestions * 0.8));
|
|
24355
24495
|
} catch (error) {
|
|
24356
24496
|
console.error("❌ AutocompletePlugin: AI suggestions failed:", error);
|
|
@@ -24359,7 +24499,7 @@ function AutocompletePlugin({
|
|
|
24359
24499
|
setIsLoading(false);
|
|
24360
24500
|
}
|
|
24361
24501
|
},
|
|
24362
|
-
[enableAI, minMatchLength, maxSuggestions]
|
|
24502
|
+
[enableAI, minMatchLength, maxSuggestions, editor]
|
|
24363
24503
|
);
|
|
24364
24504
|
const getTraditionalSuggestions = useCallback(
|
|
24365
24505
|
(query) => {
|
|
@@ -24416,7 +24556,6 @@ function AutocompletePlugin({
|
|
|
24416
24556
|
}, 100);
|
|
24417
24557
|
return;
|
|
24418
24558
|
}
|
|
24419
|
-
console.log("🎯 AutocompletePlugin: Checking for autocomplete trigger");
|
|
24420
24559
|
editor.update(() => {
|
|
24421
24560
|
const selection = $getSelection();
|
|
24422
24561
|
if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
@@ -24431,6 +24570,10 @@ function AutocompletePlugin({
|
|
|
24431
24570
|
while (wordStart > 0 && /[a-zA-Z0-9_']/.test(textContent[wordStart - 1])) {
|
|
24432
24571
|
wordStart--;
|
|
24433
24572
|
}
|
|
24573
|
+
if (wordStart > 0 && textContent[wordStart - 1] === "/") {
|
|
24574
|
+
setQueryString(null);
|
|
24575
|
+
return;
|
|
24576
|
+
}
|
|
24434
24577
|
const currentWord = textContent.slice(wordStart, anchorOffset);
|
|
24435
24578
|
if (currentWord.length >= minMatchLength) {
|
|
24436
24579
|
setQueryString(currentWord);
|
|
@@ -24445,18 +24588,10 @@ function AutocompletePlugin({
|
|
|
24445
24588
|
}
|
|
24446
24589
|
if (queryString && !justSelectedOption.current) {
|
|
24447
24590
|
debounceTimer.current = setTimeout(async () => {
|
|
24448
|
-
console.log(
|
|
24449
|
-
"🔄 AutocompletePlugin: Getting suggestions for:",
|
|
24450
|
-
queryString
|
|
24451
|
-
);
|
|
24452
24591
|
const newSuggestions = await getCombinedSuggestions(queryString);
|
|
24453
24592
|
setSuggestions(newSuggestions);
|
|
24454
24593
|
setSelectedIndex(0);
|
|
24455
24594
|
onQueryChange == null ? void 0 : onQueryChange(queryString);
|
|
24456
|
-
console.log(
|
|
24457
|
-
"🎯 AutocompletePlugin: Updated suggestions:",
|
|
24458
|
-
newSuggestions
|
|
24459
|
-
);
|
|
24460
24595
|
}, debounceDelay);
|
|
24461
24596
|
} else {
|
|
24462
24597
|
setSuggestions([]);
|
|
@@ -24471,7 +24606,6 @@ function AutocompletePlugin({
|
|
|
24471
24606
|
}, [queryString, getCombinedSuggestions, onQueryChange, debounceDelay]);
|
|
24472
24607
|
const selectOption = useCallback(
|
|
24473
24608
|
(option) => {
|
|
24474
|
-
console.log("✅ AutocompletePlugin: Selecting option:", option);
|
|
24475
24609
|
justSelectedOption.current = true;
|
|
24476
24610
|
editor.update(() => {
|
|
24477
24611
|
const selection = $getSelection();
|
|
@@ -24509,9 +24643,6 @@ function AutocompletePlugin({
|
|
|
24509
24643
|
const newOffset = sentenceStart + option.displayText.length;
|
|
24510
24644
|
selection.anchor.set(textNode.getKey(), newOffset, "text");
|
|
24511
24645
|
selection.focus.set(textNode.getKey(), newOffset, "text");
|
|
24512
|
-
console.log(
|
|
24513
|
-
"✅ AutocompletePlugin: Sentence replaced successfully"
|
|
24514
|
-
);
|
|
24515
24646
|
}
|
|
24516
24647
|
} else {
|
|
24517
24648
|
let wordStart = anchorOffset;
|
|
@@ -24525,7 +24656,6 @@ function AutocompletePlugin({
|
|
|
24525
24656
|
const newOffset = wordStart + option.displayText.length;
|
|
24526
24657
|
selection.anchor.set(textNode.getKey(), newOffset, "text");
|
|
24527
24658
|
selection.focus.set(textNode.getKey(), newOffset, "text");
|
|
24528
|
-
console.log("✅ AutocompletePlugin: Word replaced successfully");
|
|
24529
24659
|
}
|
|
24530
24660
|
}
|
|
24531
24661
|
});
|
|
@@ -24629,151 +24759,373 @@ function AutocompletePlugin({
|
|
|
24629
24759
|
inputListener();
|
|
24630
24760
|
};
|
|
24631
24761
|
}, [editor, checkForAutocompleteTrigger]);
|
|
24632
|
-
const
|
|
24633
|
-
|
|
24634
|
-
return { top: 0, left: 0 };
|
|
24635
|
-
editor.update(() => {
|
|
24762
|
+
const checkGrammar = useCallback(async () => {
|
|
24763
|
+
const isSlashActive = editor.getEditorState().read(() => {
|
|
24636
24764
|
const selection = $getSelection();
|
|
24637
24765
|
if (!$isRangeSelection(selection))
|
|
24638
|
-
return;
|
|
24639
|
-
const
|
|
24640
|
-
|
|
24641
|
-
|
|
24642
|
-
const
|
|
24643
|
-
|
|
24644
|
-
|
|
24645
|
-
|
|
24646
|
-
currentElement.style.top = `${rect.bottom + window.scrollY + 4}px`;
|
|
24647
|
-
currentElement.style.left = `${rect.left + window.scrollX}px`;
|
|
24766
|
+
return false;
|
|
24767
|
+
const anchor = selection.anchor;
|
|
24768
|
+
const anchorNode = anchor.getNode();
|
|
24769
|
+
const anchorOffset = anchor.offset;
|
|
24770
|
+
const textContent = anchorNode.getTextContent();
|
|
24771
|
+
let wordStart = anchorOffset;
|
|
24772
|
+
while (wordStart > 0 && /[a-zA-Z0-9_']/.test(textContent[wordStart - 1])) {
|
|
24773
|
+
wordStart--;
|
|
24648
24774
|
}
|
|
24775
|
+
return wordStart > 0 && textContent[wordStart - 1] === "/";
|
|
24649
24776
|
});
|
|
24650
|
-
|
|
24651
|
-
|
|
24652
|
-
|
|
24653
|
-
calculateMenuPosition();
|
|
24777
|
+
if (isSlashActive) {
|
|
24778
|
+
setErrors([]);
|
|
24779
|
+
return;
|
|
24654
24780
|
}
|
|
24655
|
-
|
|
24656
|
-
|
|
24657
|
-
|
|
24658
|
-
anchor.style.position = "absolute";
|
|
24659
|
-
anchor.style.zIndex = "1000";
|
|
24660
|
-
if (anchorElementRef.current && document.body.contains(anchorElementRef.current)) {
|
|
24661
|
-
try {
|
|
24662
|
-
document.body.removeChild(anchorElementRef.current);
|
|
24663
|
-
} catch (error) {
|
|
24664
|
-
console.warn(
|
|
24665
|
-
"🚨 AutocompletePlugin: Error removing existing anchor:",
|
|
24666
|
-
error
|
|
24667
|
-
);
|
|
24668
|
-
}
|
|
24781
|
+
const text = editor.getEditorState().read(() => $getRoot().getTextContent());
|
|
24782
|
+
if (text === lastCheckedText.current) {
|
|
24783
|
+
return;
|
|
24669
24784
|
}
|
|
24670
|
-
|
|
24671
|
-
|
|
24672
|
-
setAnchorElement(anchor);
|
|
24673
|
-
return () => {
|
|
24674
|
-
if (anchorElementRef.current && document.body.contains(anchorElementRef.current)) {
|
|
24675
|
-
try {
|
|
24676
|
-
document.body.removeChild(anchorElementRef.current);
|
|
24677
|
-
} catch (error) {
|
|
24678
|
-
console.warn("🚨 AutocompletePlugin: Error during cleanup:", error);
|
|
24679
|
-
}
|
|
24680
|
-
}
|
|
24681
|
-
};
|
|
24682
|
-
}, []);
|
|
24683
|
-
const getSuggestionIcon = (type) => {
|
|
24684
|
-
switch (type) {
|
|
24685
|
-
case "spelling":
|
|
24686
|
-
return /* @__PURE__ */ jsx(CheckCircle, { className: "cteditor-size-4" });
|
|
24687
|
-
case "correction":
|
|
24688
|
-
return /* @__PURE__ */ jsx(Type, { className: "cteditor-size-4" });
|
|
24689
|
-
case "enhancement":
|
|
24690
|
-
return /* @__PURE__ */ jsx(Lightbulb, { className: "cteditor-size-4" });
|
|
24691
|
-
default:
|
|
24692
|
-
return /* @__PURE__ */ jsx(Sparkles, { className: "cteditor-size-4" });
|
|
24785
|
+
if (Math.abs(text.length - lastCheckedText.current.length) > 20) {
|
|
24786
|
+
setUserDismissed(false);
|
|
24693
24787
|
}
|
|
24694
|
-
|
|
24695
|
-
|
|
24696
|
-
|
|
24697
|
-
|
|
24698
|
-
return "destructive";
|
|
24699
|
-
case "correction":
|
|
24700
|
-
return "default";
|
|
24701
|
-
case "enhancement":
|
|
24702
|
-
return "secondary";
|
|
24703
|
-
default:
|
|
24704
|
-
return "outline";
|
|
24788
|
+
lastCheckedText.current = text;
|
|
24789
|
+
if (!text || text.trim().length < 3) {
|
|
24790
|
+
setErrors([]);
|
|
24791
|
+
return;
|
|
24705
24792
|
}
|
|
24706
|
-
|
|
24707
|
-
|
|
24708
|
-
|
|
24709
|
-
|
|
24710
|
-
|
|
24711
|
-
|
|
24712
|
-
|
|
24713
|
-
|
|
24714
|
-
|
|
24715
|
-
|
|
24716
|
-
|
|
24717
|
-
|
|
24718
|
-
|
|
24719
|
-
|
|
24720
|
-
|
|
24721
|
-
|
|
24722
|
-
|
|
24723
|
-
|
|
24724
|
-
|
|
24725
|
-
|
|
24726
|
-
|
|
24727
|
-
|
|
24728
|
-
|
|
24729
|
-
|
|
24730
|
-
|
|
24731
|
-
|
|
24732
|
-
|
|
24733
|
-
|
|
24734
|
-
|
|
24735
|
-
|
|
24736
|
-
|
|
24737
|
-
|
|
24738
|
-
|
|
24739
|
-
|
|
24740
|
-
|
|
24741
|
-
|
|
24742
|
-
|
|
24743
|
-
|
|
24744
|
-
|
|
24745
|
-
|
|
24746
|
-
|
|
24747
|
-
|
|
24748
|
-
|
|
24749
|
-
|
|
24750
|
-
|
|
24751
|
-
|
|
24752
|
-
|
|
24753
|
-
|
|
24754
|
-
|
|
24755
|
-
|
|
24756
|
-
|
|
24757
|
-
|
|
24758
|
-
|
|
24759
|
-
|
|
24760
|
-
|
|
24761
|
-
|
|
24762
|
-
|
|
24763
|
-
|
|
24764
|
-
|
|
24765
|
-
onClick: () => {
|
|
24766
|
-
setQueryString(null);
|
|
24767
|
-
setSuggestions([]);
|
|
24768
|
-
updateToolbarState("isAutocompleteEnabled", false);
|
|
24769
|
-
},
|
|
24770
|
-
children: [
|
|
24771
|
-
/* @__PURE__ */ jsx(Ban, { className: "!cteditor-size-3" }),
|
|
24772
|
-
"Disable Autocorrection"
|
|
24773
|
-
]
|
|
24793
|
+
const foundErrors = await grammarService.current.check(text);
|
|
24794
|
+
setErrors(foundErrors);
|
|
24795
|
+
}, [editor]);
|
|
24796
|
+
useEffect$1(() => {
|
|
24797
|
+
const unregister = editor.registerUpdateListener(() => {
|
|
24798
|
+
clearTimeout(checkTimeout.current);
|
|
24799
|
+
checkTimeout.current = window.setTimeout(checkGrammar, 2e3);
|
|
24800
|
+
});
|
|
24801
|
+
return () => {
|
|
24802
|
+
unregister();
|
|
24803
|
+
clearTimeout(checkTimeout.current);
|
|
24804
|
+
};
|
|
24805
|
+
}, [editor, checkGrammar]);
|
|
24806
|
+
useEffect$1(() => {
|
|
24807
|
+
highlightElementsRef.current.forEach((el) => {
|
|
24808
|
+
el.classList.remove("spelling-error", "grammar-error");
|
|
24809
|
+
});
|
|
24810
|
+
highlightElementsRef.current = [];
|
|
24811
|
+
if (errors.length === 0 || userDismissed)
|
|
24812
|
+
return;
|
|
24813
|
+
const timeoutId = setTimeout(() => {
|
|
24814
|
+
const editorElement = document.querySelector(".ContentEditable__root");
|
|
24815
|
+
if (!editorElement)
|
|
24816
|
+
return;
|
|
24817
|
+
const walker = document.createTreeWalker(
|
|
24818
|
+
editorElement,
|
|
24819
|
+
NodeFilter.SHOW_TEXT,
|
|
24820
|
+
null
|
|
24821
|
+
);
|
|
24822
|
+
const textNodes = [];
|
|
24823
|
+
let node;
|
|
24824
|
+
while (node = walker.nextNode()) {
|
|
24825
|
+
textNodes.push(node);
|
|
24826
|
+
}
|
|
24827
|
+
errors.forEach((error) => {
|
|
24828
|
+
textNodes.forEach((textNode) => {
|
|
24829
|
+
const nodeText = textNode.textContent || "";
|
|
24830
|
+
const errorIndex = nodeText.toLowerCase().indexOf(error.original.toLowerCase());
|
|
24831
|
+
if (errorIndex !== -1 && textNode.parentElement) {
|
|
24832
|
+
const className = error.type === "spelling" ? "spelling-error" : "grammar-error";
|
|
24833
|
+
if (textNode.parentElement.tagName === "SPAN") {
|
|
24834
|
+
textNode.parentElement.classList.add(className);
|
|
24835
|
+
highlightElementsRef.current.push(textNode.parentElement);
|
|
24836
|
+
} else if (textNode.parentElement) {
|
|
24837
|
+
const range = document.createRange();
|
|
24838
|
+
range.setStart(textNode, errorIndex);
|
|
24839
|
+
range.setEnd(textNode, Math.min(errorIndex + error.original.length, nodeText.length));
|
|
24840
|
+
const span = document.createElement("span");
|
|
24841
|
+
span.className = className;
|
|
24842
|
+
span.setAttribute("data-error-type", error.type);
|
|
24843
|
+
try {
|
|
24844
|
+
range.surroundContents(span);
|
|
24845
|
+
highlightElementsRef.current.push(span);
|
|
24846
|
+
} catch (e) {
|
|
24847
|
+
if (textNode.parentElement) {
|
|
24848
|
+
textNode.parentElement.classList.add(className);
|
|
24849
|
+
highlightElementsRef.current.push(textNode.parentElement);
|
|
24850
|
+
}
|
|
24851
|
+
}
|
|
24774
24852
|
}
|
|
24775
|
-
|
|
24776
|
-
|
|
24853
|
+
}
|
|
24854
|
+
});
|
|
24855
|
+
});
|
|
24856
|
+
}, 100);
|
|
24857
|
+
return () => clearTimeout(timeoutId);
|
|
24858
|
+
}, [errors, userDismissed]);
|
|
24859
|
+
const applyCorrection = useCallback(
|
|
24860
|
+
(suggestion, original, errorType) => {
|
|
24861
|
+
editor.update(() => {
|
|
24862
|
+
const root2 = $getRoot();
|
|
24863
|
+
const currentText = root2.getTextContent();
|
|
24864
|
+
const isSpellingError = errorType === "spelling";
|
|
24865
|
+
let newText = currentText;
|
|
24866
|
+
if (isSpellingError) {
|
|
24867
|
+
const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
24868
|
+
const regex = new RegExp(`\\b${escapedOriginal}\\b`, "gi");
|
|
24869
|
+
newText = currentText.replace(regex, suggestion);
|
|
24870
|
+
} else {
|
|
24871
|
+
const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
24872
|
+
const regex = new RegExp(escapedOriginal, "gi");
|
|
24873
|
+
if (currentText.toLowerCase().includes(original.toLowerCase())) {
|
|
24874
|
+
newText = currentText.replace(regex, suggestion);
|
|
24875
|
+
} else {
|
|
24876
|
+
newText = suggestion;
|
|
24877
|
+
}
|
|
24878
|
+
}
|
|
24879
|
+
root2.clear();
|
|
24880
|
+
const paragraph = $createParagraphNode();
|
|
24881
|
+
const textNode = $createTextNode(newText);
|
|
24882
|
+
paragraph.append(textNode);
|
|
24883
|
+
root2.append(paragraph);
|
|
24884
|
+
});
|
|
24885
|
+
setTimeout(() => {
|
|
24886
|
+
lastCheckedText.current = "";
|
|
24887
|
+
checkGrammar();
|
|
24888
|
+
}, 100);
|
|
24889
|
+
},
|
|
24890
|
+
[editor, checkGrammar]
|
|
24891
|
+
);
|
|
24892
|
+
const calculateMenuPosition = useCallback(() => {
|
|
24893
|
+
if (!anchorElement)
|
|
24894
|
+
return { top: 0, left: 0 };
|
|
24895
|
+
editor.update(() => {
|
|
24896
|
+
const selection = $getSelection();
|
|
24897
|
+
if (!$isRangeSelection(selection))
|
|
24898
|
+
return;
|
|
24899
|
+
const domSelection = window.getSelection();
|
|
24900
|
+
if (!domSelection || domSelection.rangeCount === 0)
|
|
24901
|
+
return;
|
|
24902
|
+
const range = domSelection.getRangeAt(0);
|
|
24903
|
+
const rect = range.getBoundingClientRect();
|
|
24904
|
+
if (anchorElementRef.current) {
|
|
24905
|
+
const currentElement = anchorElementRef.current;
|
|
24906
|
+
currentElement.style.top = `${rect.bottom + window.scrollY + 4}px`;
|
|
24907
|
+
currentElement.style.left = `${rect.left + window.scrollX}px`;
|
|
24908
|
+
}
|
|
24909
|
+
});
|
|
24910
|
+
}, [editor, anchorElement]);
|
|
24911
|
+
useEffect$1(() => {
|
|
24912
|
+
if (suggestions.length > 0) {
|
|
24913
|
+
calculateMenuPosition();
|
|
24914
|
+
}
|
|
24915
|
+
}, [suggestions, calculateMenuPosition]);
|
|
24916
|
+
useEffect$1(() => {
|
|
24917
|
+
const anchor = document.createElement("div");
|
|
24918
|
+
anchor.style.position = "absolute";
|
|
24919
|
+
anchor.style.zIndex = "1000";
|
|
24920
|
+
if (anchorElementRef.current && document.body.contains(anchorElementRef.current)) {
|
|
24921
|
+
try {
|
|
24922
|
+
document.body.removeChild(anchorElementRef.current);
|
|
24923
|
+
} catch (error) {
|
|
24924
|
+
console.warn("Error removing existing anchor:", error);
|
|
24925
|
+
}
|
|
24926
|
+
}
|
|
24927
|
+
document.body.appendChild(anchor);
|
|
24928
|
+
anchorElementRef.current = anchor;
|
|
24929
|
+
setAnchorElement(anchor);
|
|
24930
|
+
return () => {
|
|
24931
|
+
if (anchorElementRef.current && document.body.contains(anchorElementRef.current)) {
|
|
24932
|
+
try {
|
|
24933
|
+
document.body.removeChild(anchorElementRef.current);
|
|
24934
|
+
} catch (error) {
|
|
24935
|
+
console.warn("Error during cleanup:", error);
|
|
24936
|
+
}
|
|
24937
|
+
}
|
|
24938
|
+
};
|
|
24939
|
+
}, []);
|
|
24940
|
+
const getSuggestionIcon = (type) => {
|
|
24941
|
+
switch (type) {
|
|
24942
|
+
case "spelling":
|
|
24943
|
+
return /* @__PURE__ */ jsx(CheckCircle, { className: "cteditor-size-4" });
|
|
24944
|
+
case "correction":
|
|
24945
|
+
return /* @__PURE__ */ jsx(Type, { className: "cteditor-size-4" });
|
|
24946
|
+
case "enhancement":
|
|
24947
|
+
return /* @__PURE__ */ jsx(Lightbulb, { className: "cteditor-size-4" });
|
|
24948
|
+
default:
|
|
24949
|
+
return /* @__PURE__ */ jsx(Sparkles, { className: "cteditor-size-4" });
|
|
24950
|
+
}
|
|
24951
|
+
};
|
|
24952
|
+
const getSuggestionVariant = (type) => {
|
|
24953
|
+
switch (type) {
|
|
24954
|
+
case "spelling":
|
|
24955
|
+
return "destructive";
|
|
24956
|
+
case "correction":
|
|
24957
|
+
return "default";
|
|
24958
|
+
case "enhancement":
|
|
24959
|
+
return "secondary";
|
|
24960
|
+
default:
|
|
24961
|
+
return "outline";
|
|
24962
|
+
}
|
|
24963
|
+
};
|
|
24964
|
+
useEffect$1(() => {
|
|
24965
|
+
const showAutocomplete2 = queryString && (suggestions.length > 0 || isLoading);
|
|
24966
|
+
const showGrammar2 = errors.length > 0 && !userDismissed;
|
|
24967
|
+
if (showAutocomplete2 && !showGrammar2) {
|
|
24968
|
+
setActiveTab("autocomplete");
|
|
24969
|
+
} else if (showGrammar2 && !showAutocomplete2) {
|
|
24970
|
+
setActiveTab("grammar");
|
|
24971
|
+
}
|
|
24972
|
+
}, [queryString, suggestions.length, isLoading, errors.length, userDismissed]);
|
|
24973
|
+
const showAutocomplete = queryString && (suggestions.length > 0 || isLoading);
|
|
24974
|
+
const showGrammar = errors.length > 0 && !userDismissed;
|
|
24975
|
+
if (!anchorElement || !showAutocomplete && !showGrammar) {
|
|
24976
|
+
return null;
|
|
24977
|
+
}
|
|
24978
|
+
return createPortal(
|
|
24979
|
+
/* @__PURE__ */ jsxs(
|
|
24980
|
+
Card,
|
|
24981
|
+
{
|
|
24982
|
+
ref: menuRef,
|
|
24983
|
+
className: "cteditor-w-80 cteditor-max-h-64 cteditor-overflow-hidden cteditor-shadow-lg cteditor-border cteditor-bg-background cteditor-rounded-md",
|
|
24984
|
+
children: [
|
|
24985
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-border-b cteditor-bg-muted/30", children: [
|
|
24986
|
+
/* @__PURE__ */ jsxs(
|
|
24987
|
+
"button",
|
|
24988
|
+
{
|
|
24989
|
+
onClick: () => setActiveTab("autocomplete"),
|
|
24990
|
+
className: cn$1(
|
|
24991
|
+
"cteditor-flex-1 cteditor-px-4 cteditor-py-2 cteditor-text-sm cteditor-font-medium cteditor-transition-colors",
|
|
24992
|
+
activeTab === "autocomplete" ? "cteditor-bg-background cteditor-text-foreground cteditor-border-b-2 cteditor-border-primary" : "cteditor-text-muted-foreground hover:cteditor-text-foreground"
|
|
24993
|
+
),
|
|
24994
|
+
children: [
|
|
24995
|
+
/* @__PURE__ */ jsx(Sparkles, { className: "cteditor-inline cteditor-size-4 cteditor-mr-2" }),
|
|
24996
|
+
"Autocomplete"
|
|
24997
|
+
]
|
|
24998
|
+
}
|
|
24999
|
+
),
|
|
25000
|
+
/* @__PURE__ */ jsxs(
|
|
25001
|
+
"button",
|
|
25002
|
+
{
|
|
25003
|
+
onClick: () => setActiveTab("grammar"),
|
|
25004
|
+
className: cn$1(
|
|
25005
|
+
"cteditor-flex-1 cteditor-px-4 cteditor-py-2 cteditor-text-sm cteditor-font-medium cteditor-transition-colors",
|
|
25006
|
+
activeTab === "grammar" ? "cteditor-bg-background cteditor-text-foreground cteditor-border-b-2 cteditor-border-primary" : "cteditor-text-muted-foreground hover:cteditor-text-foreground"
|
|
25007
|
+
),
|
|
25008
|
+
children: [
|
|
25009
|
+
/* @__PURE__ */ jsx(CheckCircle, { className: "cteditor-inline cteditor-size-4 cteditor-mr-2" }),
|
|
25010
|
+
"Grammar & Spelling",
|
|
25011
|
+
errors.length > 0 && /* @__PURE__ */ jsx(Badge, { variant: "destructive", className: "cteditor-ml-2 cteditor-text-xs", children: errors.length })
|
|
25012
|
+
]
|
|
25013
|
+
}
|
|
25014
|
+
)
|
|
25015
|
+
] }),
|
|
25016
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "cteditor-p-2 cteditor-max-h-56 cteditor-overflow-y-auto", children: [
|
|
25017
|
+
activeTab === "autocomplete" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25018
|
+
isLoading && /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-p-3 cteditor-text-sm cteditor-text-muted-foreground", children: [
|
|
25019
|
+
/* @__PURE__ */ jsx(Skeleton, { className: "cteditor-h-4 cteditor-w-4 cteditor-rounded-full" }),
|
|
25020
|
+
/* @__PURE__ */ jsx("span", { children: "Getting AI suggestions..." })
|
|
25021
|
+
] }),
|
|
25022
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-space-y-1", children: suggestions.map((option, index2) => /* @__PURE__ */ jsxs(
|
|
25023
|
+
"div",
|
|
25024
|
+
{
|
|
25025
|
+
className: cn$1(
|
|
25026
|
+
"cteditor-flex cteditor-items-start cteditor-gap-3 cteditor-p-3 cteditor-rounded-md cteditor-cursor-pointer cteditor-transition-colors cteditor-text-sm",
|
|
25027
|
+
index2 === selectedIndex ? "cteditor-bg-foreground/5" : "hover:cteditor-bg-muted/50"
|
|
25028
|
+
),
|
|
25029
|
+
onClick: () => selectOption(option),
|
|
25030
|
+
onMouseEnter: () => setSelectedIndex(index2),
|
|
25031
|
+
children: [
|
|
25032
|
+
/* @__PURE__ */ jsx(
|
|
25033
|
+
"div",
|
|
25034
|
+
{
|
|
25035
|
+
className: cn$1(
|
|
25036
|
+
"cteditor-mt-0.5",
|
|
25037
|
+
index2 === selectedIndex ? "cteditor-text-primary" : "cteditor-text-primary"
|
|
25038
|
+
),
|
|
25039
|
+
children: getSuggestionIcon(option.type)
|
|
25040
|
+
}
|
|
25041
|
+
),
|
|
25042
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex-1 cteditor-min-w-0", children: [
|
|
25043
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-mb-2", children: [
|
|
25044
|
+
/* @__PURE__ */ jsx(
|
|
25045
|
+
Badge,
|
|
25046
|
+
{
|
|
25047
|
+
variant: index2 === selectedIndex ? "secondary" : getSuggestionVariant(option.type),
|
|
25048
|
+
className: "cteditor-text-xs cteditor-border cteditor-border-foreground/20 cteditor-rounded-2xl !cteditor-font-normal",
|
|
25049
|
+
children: option.type
|
|
25050
|
+
}
|
|
25051
|
+
),
|
|
25052
|
+
option.confidence && /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-px-2 cteditor-py-0.5 cteditor-rounded-md cteditor-bg-muted/50 cteditor-text-foreground", children: option.confidence })
|
|
25053
|
+
] }),
|
|
25054
|
+
/* @__PURE__ */ jsx("p", { className: "cteditor-leading-relaxed cteditor-break-words", children: option.displayText })
|
|
25055
|
+
] })
|
|
25056
|
+
]
|
|
25057
|
+
},
|
|
25058
|
+
option.key
|
|
25059
|
+
)) }),
|
|
25060
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-mt-1 cteditor-pt-1 cteditor-border-t cteditor-sticky cteditor-bottom-0 cteditor-bg-background", children: /* @__PURE__ */ jsxs(
|
|
25061
|
+
Button,
|
|
25062
|
+
{
|
|
25063
|
+
variant: "ghost",
|
|
25064
|
+
size: "sm",
|
|
25065
|
+
className: "cteditor-w-full cteditor-justify-start cteditor-gap-2 cteditor-text-muted-foreground hover:cteditor-text-foreground",
|
|
25066
|
+
onClick: () => {
|
|
25067
|
+
setQueryString(null);
|
|
25068
|
+
setSuggestions([]);
|
|
25069
|
+
updateToolbarState("isAutocompleteEnabled", false);
|
|
25070
|
+
},
|
|
25071
|
+
children: [
|
|
25072
|
+
/* @__PURE__ */ jsx(Ban, { className: "!cteditor-size-3" }),
|
|
25073
|
+
"Disable Autocomplete & Grammar Check"
|
|
25074
|
+
]
|
|
25075
|
+
}
|
|
25076
|
+
) })
|
|
25077
|
+
] }),
|
|
25078
|
+
activeTab === "grammar" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25079
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-space-y-2 cteditor-p-2", children: errors.map((error, idx) => /* @__PURE__ */ jsx(
|
|
25080
|
+
"div",
|
|
25081
|
+
{
|
|
25082
|
+
className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-p-3 cteditor-rounded-md cteditor-bg-muted/50 cteditor-border",
|
|
25083
|
+
children: /* @__PURE__ */ jsxs("div", { className: "cteditor-flex-1", children: [
|
|
25084
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-mb-1", children: [
|
|
25085
|
+
/* @__PURE__ */ jsx(
|
|
25086
|
+
Badge,
|
|
25087
|
+
{
|
|
25088
|
+
variant: error.type === "spelling" ? "destructive" : "default",
|
|
25089
|
+
className: "cteditor-text-xs",
|
|
25090
|
+
children: error.type
|
|
25091
|
+
}
|
|
25092
|
+
),
|
|
25093
|
+
error.confidence && /* @__PURE__ */ jsx("span", { className: "cteditor-text-xs cteditor-text-muted-foreground", children: error.confidence })
|
|
25094
|
+
] }),
|
|
25095
|
+
/* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-line-through cteditor-text-red-600 cteditor-mb-1", children: error.original }),
|
|
25096
|
+
error.suggestions.length > 0 && /* @__PURE__ */ jsx("div", { className: "cteditor-space-y-1", children: error.suggestions.slice(0, 2).map((suggestion, sIdx) => /* @__PURE__ */ jsx(
|
|
25097
|
+
"button",
|
|
25098
|
+
{
|
|
25099
|
+
onClick: () => applyCorrection(suggestion, error.original, error.type),
|
|
25100
|
+
className: "cteditor-block cteditor-w-full cteditor-text-left cteditor-text-sm cteditor-text-green-600 hover:cteditor-text-green-700 cteditor-px-2 cteditor-py-1 cteditor-rounded cteditor-bg-green-50 hover:cteditor-bg-green-100",
|
|
25101
|
+
children: suggestion
|
|
25102
|
+
},
|
|
25103
|
+
sIdx
|
|
25104
|
+
)) })
|
|
25105
|
+
] })
|
|
25106
|
+
},
|
|
25107
|
+
idx
|
|
25108
|
+
)) }),
|
|
25109
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-mt-1 cteditor-pt-1 cteditor-border-t cteditor-sticky cteditor-bottom-0 cteditor-bg-background", children: /* @__PURE__ */ jsxs(
|
|
25110
|
+
Button,
|
|
25111
|
+
{
|
|
25112
|
+
variant: "ghost",
|
|
25113
|
+
size: "sm",
|
|
25114
|
+
className: "cteditor-w-full cteditor-justify-start cteditor-gap-2 cteditor-text-muted-foreground hover:cteditor-text-foreground",
|
|
25115
|
+
onClick: () => {
|
|
25116
|
+
setUserDismissed(true);
|
|
25117
|
+
setErrors([]);
|
|
25118
|
+
updateToolbarState("isGrammarCheckEnabled", false);
|
|
25119
|
+
},
|
|
25120
|
+
children: [
|
|
25121
|
+
/* @__PURE__ */ jsx(Ban, { className: "!cteditor-size-3" }),
|
|
25122
|
+
"Disable Autocomplete & Grammar Check"
|
|
25123
|
+
]
|
|
25124
|
+
}
|
|
25125
|
+
) })
|
|
25126
|
+
] })
|
|
25127
|
+
] })
|
|
25128
|
+
]
|
|
24777
25129
|
}
|
|
24778
25130
|
),
|
|
24779
25131
|
anchorElement
|
|
@@ -24973,11 +25325,179 @@ const CommentBubblePlugin = () => {
|
|
|
24973
25325
|
}, [editor, getCommentById]);
|
|
24974
25326
|
return null;
|
|
24975
25327
|
};
|
|
24976
|
-
const
|
|
24977
|
-
|
|
24978
|
-
|
|
24979
|
-
|
|
24980
|
-
|
|
25328
|
+
const ACCEPTABLE_IMAGE_TYPES = [
|
|
25329
|
+
"image/",
|
|
25330
|
+
"image/heic",
|
|
25331
|
+
"image/heif",
|
|
25332
|
+
"image/gif",
|
|
25333
|
+
"image/webp",
|
|
25334
|
+
"image/png",
|
|
25335
|
+
"image/jpg",
|
|
25336
|
+
"image/jpeg",
|
|
25337
|
+
"image/svg+xml"
|
|
25338
|
+
];
|
|
25339
|
+
const ACCEPTABLE_APPLICATION_TYPES = [
|
|
25340
|
+
"application/pdf",
|
|
25341
|
+
"application/msword",
|
|
25342
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
25343
|
+
];
|
|
25344
|
+
const fileToDataURL = (file) => {
|
|
25345
|
+
return new Promise((resolve, reject) => {
|
|
25346
|
+
const reader = new FileReader();
|
|
25347
|
+
reader.onload = () => resolve(reader.result);
|
|
25348
|
+
reader.onerror = reject;
|
|
25349
|
+
reader.readAsDataURL(file);
|
|
25350
|
+
});
|
|
25351
|
+
};
|
|
25352
|
+
function DragDropPaste() {
|
|
25353
|
+
const [editor] = useLexicalComposerContext();
|
|
25354
|
+
const [isDragging, setIsDragging] = useState$1(false);
|
|
25355
|
+
const apiKey = void 0;
|
|
25356
|
+
const { uploadFileToS3 } = useS3Uploader(apiKey);
|
|
25357
|
+
useEffect$1(() => {
|
|
25358
|
+
const handleDragEnter = (e) => {
|
|
25359
|
+
var _a, _b;
|
|
25360
|
+
e.preventDefault();
|
|
25361
|
+
e.stopPropagation();
|
|
25362
|
+
const hasFiles = (_a = e.dataTransfer) == null ? void 0 : _a.types.includes("Files");
|
|
25363
|
+
const hasImages = (_b = e.dataTransfer) == null ? void 0 : _b.types.some(
|
|
25364
|
+
(type) => type === "text/html" || type === "text/uri-list"
|
|
25365
|
+
);
|
|
25366
|
+
if (hasFiles || hasImages) {
|
|
25367
|
+
setIsDragging(true);
|
|
25368
|
+
const editorEl = editor.getRootElement();
|
|
25369
|
+
if (editorEl) {
|
|
25370
|
+
editorEl.style.backgroundColor = "rgba(59, 130, 246, 0.05)";
|
|
25371
|
+
editorEl.style.border = "2px dashed rgb(59, 130, 246)";
|
|
25372
|
+
editorEl.style.borderRadius = "8px";
|
|
25373
|
+
}
|
|
25374
|
+
}
|
|
25375
|
+
};
|
|
25376
|
+
const handleDragOver = (e) => {
|
|
25377
|
+
e.preventDefault();
|
|
25378
|
+
e.stopPropagation();
|
|
25379
|
+
if (e.dataTransfer) {
|
|
25380
|
+
e.dataTransfer.dropEffect = "copy";
|
|
25381
|
+
}
|
|
25382
|
+
};
|
|
25383
|
+
const handleDragLeave = (e) => {
|
|
25384
|
+
e.preventDefault();
|
|
25385
|
+
e.stopPropagation();
|
|
25386
|
+
const editorEl = editor.getRootElement();
|
|
25387
|
+
if (e.relatedTarget === null || editorEl && !editorEl.contains(e.relatedTarget)) {
|
|
25388
|
+
setIsDragging(false);
|
|
25389
|
+
if (editorEl) {
|
|
25390
|
+
editorEl.style.backgroundColor = "";
|
|
25391
|
+
editorEl.style.border = "";
|
|
25392
|
+
editorEl.style.borderRadius = "";
|
|
25393
|
+
}
|
|
25394
|
+
}
|
|
25395
|
+
};
|
|
25396
|
+
const handleDrop = (e) => {
|
|
25397
|
+
var _a, _b, _c;
|
|
25398
|
+
e.preventDefault();
|
|
25399
|
+
e.stopPropagation();
|
|
25400
|
+
setIsDragging(false);
|
|
25401
|
+
const editorEl = editor.getRootElement();
|
|
25402
|
+
if (editorEl) {
|
|
25403
|
+
editorEl.style.backgroundColor = "";
|
|
25404
|
+
editorEl.style.border = "";
|
|
25405
|
+
editorEl.style.borderRadius = "";
|
|
25406
|
+
}
|
|
25407
|
+
const files = (_a = e.dataTransfer) == null ? void 0 : _a.files;
|
|
25408
|
+
if (files && files.length > 0) {
|
|
25409
|
+
console.log("File drop detected, letting DRAG_DROP_PASTE command handle it");
|
|
25410
|
+
return;
|
|
25411
|
+
}
|
|
25412
|
+
const html = (_b = e.dataTransfer) == null ? void 0 : _b.getData("text/html");
|
|
25413
|
+
if (html) {
|
|
25414
|
+
const tempDiv = document.createElement("div");
|
|
25415
|
+
tempDiv.innerHTML = html;
|
|
25416
|
+
const img = tempDiv.querySelector("img");
|
|
25417
|
+
if (img && img.src) {
|
|
25418
|
+
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
25419
|
+
altText: img.alt || "Dragged image",
|
|
25420
|
+
src: img.src
|
|
25421
|
+
});
|
|
25422
|
+
console.log("Image from web browser inserted:", img.src);
|
|
25423
|
+
return;
|
|
25424
|
+
}
|
|
25425
|
+
}
|
|
25426
|
+
const uriList = (_c = e.dataTransfer) == null ? void 0 : _c.getData("text/uri-list");
|
|
25427
|
+
if (uriList) {
|
|
25428
|
+
const urls = uriList.split("\n").filter((url) => url.trim().length > 0);
|
|
25429
|
+
urls.forEach((url) => {
|
|
25430
|
+
if (/\.(jpg|jpeg|png|gif|webp|svg)$/i.test(url)) {
|
|
25431
|
+
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
25432
|
+
altText: "Dragged image",
|
|
25433
|
+
src: url.trim()
|
|
25434
|
+
});
|
|
25435
|
+
console.log("Image from URL inserted:", url);
|
|
25436
|
+
}
|
|
25437
|
+
});
|
|
25438
|
+
}
|
|
25439
|
+
};
|
|
25440
|
+
const editorElement = editor.getRootElement();
|
|
25441
|
+
if (editorElement) {
|
|
25442
|
+
editorElement.addEventListener("dragenter", handleDragEnter);
|
|
25443
|
+
editorElement.addEventListener("dragover", handleDragOver);
|
|
25444
|
+
editorElement.addEventListener("dragleave", handleDragLeave);
|
|
25445
|
+
editorElement.addEventListener("drop", handleDrop);
|
|
25446
|
+
return () => {
|
|
25447
|
+
editorElement.removeEventListener("dragenter", handleDragEnter);
|
|
25448
|
+
editorElement.removeEventListener("dragover", handleDragOver);
|
|
25449
|
+
editorElement.removeEventListener("dragleave", handleDragLeave);
|
|
25450
|
+
editorElement.removeEventListener("drop", handleDrop);
|
|
25451
|
+
};
|
|
25452
|
+
}
|
|
25453
|
+
}, [editor]);
|
|
25454
|
+
useEffect$1(() => {
|
|
25455
|
+
return editor.registerCommand(
|
|
25456
|
+
DRAG_DROP_PASTE,
|
|
25457
|
+
(files) => {
|
|
25458
|
+
(async () => {
|
|
25459
|
+
const filesResult = await mediaFileReader(files, [
|
|
25460
|
+
...ACCEPTABLE_IMAGE_TYPES,
|
|
25461
|
+
...ACCEPTABLE_APPLICATION_TYPES
|
|
25462
|
+
]);
|
|
25463
|
+
for (const { file, result } of filesResult) {
|
|
25464
|
+
let fileUrl;
|
|
25465
|
+
try {
|
|
25466
|
+
if (apiKey)
|
|
25467
|
+
;
|
|
25468
|
+
else {
|
|
25469
|
+
fileUrl = await fileToDataURL(file);
|
|
25470
|
+
console.log("Using local data URL (no S3 upload)");
|
|
25471
|
+
}
|
|
25472
|
+
} catch (error) {
|
|
25473
|
+
console.error("Upload failed, using local data URL:", error);
|
|
25474
|
+
fileUrl = await fileToDataURL(file);
|
|
25475
|
+
}
|
|
25476
|
+
if (isMimeType(file, ACCEPTABLE_IMAGE_TYPES)) {
|
|
25477
|
+
editor.dispatchCommand(INSERT_IMAGE_COMMAND, {
|
|
25478
|
+
altText: file.name,
|
|
25479
|
+
src: fileUrl
|
|
25480
|
+
});
|
|
25481
|
+
} else if (isMimeType(file, ACCEPTABLE_APPLICATION_TYPES)) {
|
|
25482
|
+
editor.dispatchCommand(INSERT_FILE_COMMAND, {
|
|
25483
|
+
linkText: file.name || "Download File",
|
|
25484
|
+
src: fileUrl
|
|
25485
|
+
});
|
|
25486
|
+
}
|
|
25487
|
+
}
|
|
25488
|
+
})();
|
|
25489
|
+
return true;
|
|
25490
|
+
},
|
|
25491
|
+
COMMAND_PRIORITY_LOW
|
|
25492
|
+
);
|
|
25493
|
+
}, [editor, apiKey, uploadFileToS3]);
|
|
25494
|
+
return null;
|
|
25495
|
+
}
|
|
25496
|
+
const FloatingEmbedMenuPlugin$1 = "";
|
|
25497
|
+
function FloatingEmbedMenu({
|
|
25498
|
+
editor,
|
|
25499
|
+
anchorElem,
|
|
25500
|
+
nodeKey,
|
|
24981
25501
|
url,
|
|
24982
25502
|
onClose
|
|
24983
25503
|
}) {
|
|
@@ -26932,6 +27452,203 @@ function NewMentionsPlugin({
|
|
|
26932
27452
|
}
|
|
26933
27453
|
);
|
|
26934
27454
|
}
|
|
27455
|
+
function RichTextPastePlugin() {
|
|
27456
|
+
const [editor] = useLexicalComposerContext();
|
|
27457
|
+
useEffect$1(() => {
|
|
27458
|
+
return editor.registerCommand(
|
|
27459
|
+
PASTE_COMMAND,
|
|
27460
|
+
(event) => {
|
|
27461
|
+
const clipboardData = event.clipboardData;
|
|
27462
|
+
if (!clipboardData)
|
|
27463
|
+
return false;
|
|
27464
|
+
const htmlContent = clipboardData.getData("text/html");
|
|
27465
|
+
const plainText = clipboardData.getData("text/plain");
|
|
27466
|
+
if (htmlContent) {
|
|
27467
|
+
event.preventDefault();
|
|
27468
|
+
handleHtmlPaste(htmlContent);
|
|
27469
|
+
return true;
|
|
27470
|
+
} else if (plainText) {
|
|
27471
|
+
event.preventDefault();
|
|
27472
|
+
handleMarkdownPaste(plainText);
|
|
27473
|
+
return true;
|
|
27474
|
+
}
|
|
27475
|
+
return false;
|
|
27476
|
+
},
|
|
27477
|
+
COMMAND_PRIORITY_LOW
|
|
27478
|
+
);
|
|
27479
|
+
}, [editor]);
|
|
27480
|
+
const handleHtmlPaste = (htmlContent) => {
|
|
27481
|
+
editor.update(() => {
|
|
27482
|
+
const selection = $getSelection();
|
|
27483
|
+
if ($isRangeSelection(selection)) {
|
|
27484
|
+
const tempDiv = document.createElement("div");
|
|
27485
|
+
tempDiv.innerHTML = htmlContent;
|
|
27486
|
+
const processNode = (node) => {
|
|
27487
|
+
if (node.nodeType === Node.TEXT_NODE) {
|
|
27488
|
+
const text = node.textContent || "";
|
|
27489
|
+
const textNode = $createTextNode(text);
|
|
27490
|
+
if (node.parentElement) {
|
|
27491
|
+
if (node.parentElement.tagName === "STRONG" || node.parentElement.tagName === "B") {
|
|
27492
|
+
textNode.setFormat("bold");
|
|
27493
|
+
}
|
|
27494
|
+
if (node.parentElement.tagName === "EM" || node.parentElement.tagName === "I") {
|
|
27495
|
+
textNode.setFormat("italic");
|
|
27496
|
+
}
|
|
27497
|
+
if (node.parentElement.tagName === "U") {
|
|
27498
|
+
textNode.setFormat("underline");
|
|
27499
|
+
}
|
|
27500
|
+
if (node.parentElement.tagName === "CODE") {
|
|
27501
|
+
textNode.setFormat("code");
|
|
27502
|
+
}
|
|
27503
|
+
if (node.parentElement.tagName === "STRIKE" || node.parentElement.tagName === "S") {
|
|
27504
|
+
textNode.setFormat("strikethrough");
|
|
27505
|
+
}
|
|
27506
|
+
if (node.parentElement.tagName === "SUB") {
|
|
27507
|
+
textNode.setFormat("subscript");
|
|
27508
|
+
}
|
|
27509
|
+
if (node.parentElement.tagName === "SUP") {
|
|
27510
|
+
textNode.setFormat("superscript");
|
|
27511
|
+
}
|
|
27512
|
+
}
|
|
27513
|
+
return textNode;
|
|
27514
|
+
}
|
|
27515
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
27516
|
+
const element = node;
|
|
27517
|
+
if (element.tagName === "UL" || element.tagName === "OL") {
|
|
27518
|
+
const listNode = $createListNode(
|
|
27519
|
+
element.tagName === "UL" ? "bullet" : "number"
|
|
27520
|
+
);
|
|
27521
|
+
Array.from(element.childNodes).forEach((child) => {
|
|
27522
|
+
if (child.nodeType === Node.ELEMENT_NODE && child.tagName === "LI") {
|
|
27523
|
+
const listItemNode = $createListItemNode();
|
|
27524
|
+
Array.from(child.childNodes).forEach((grandChild) => {
|
|
27525
|
+
const processedNode = processNode(grandChild);
|
|
27526
|
+
if (processedNode) {
|
|
27527
|
+
if (Array.isArray(processedNode)) {
|
|
27528
|
+
processedNode.forEach(
|
|
27529
|
+
(node2) => listItemNode.append(node2)
|
|
27530
|
+
);
|
|
27531
|
+
} else {
|
|
27532
|
+
listItemNode.append(processedNode);
|
|
27533
|
+
}
|
|
27534
|
+
}
|
|
27535
|
+
});
|
|
27536
|
+
listNode.append(listItemNode);
|
|
27537
|
+
}
|
|
27538
|
+
});
|
|
27539
|
+
return listNode;
|
|
27540
|
+
}
|
|
27541
|
+
if (element.tagName.match(/^H[1-6]$/)) {
|
|
27542
|
+
const headingNode = $createHeadingNode(
|
|
27543
|
+
element.tagName.toLowerCase()
|
|
27544
|
+
);
|
|
27545
|
+
Array.from(element.childNodes).forEach((child) => {
|
|
27546
|
+
const processedNode = processNode(child);
|
|
27547
|
+
if (processedNode) {
|
|
27548
|
+
if (Array.isArray(processedNode)) {
|
|
27549
|
+
processedNode.forEach((node2) => headingNode.append(node2));
|
|
27550
|
+
} else {
|
|
27551
|
+
headingNode.append(processedNode);
|
|
27552
|
+
}
|
|
27553
|
+
}
|
|
27554
|
+
});
|
|
27555
|
+
return headingNode;
|
|
27556
|
+
}
|
|
27557
|
+
if (element.tagName === "P") {
|
|
27558
|
+
const paragraphNode = $createParagraphNode();
|
|
27559
|
+
Array.from(element.childNodes).forEach((child) => {
|
|
27560
|
+
const processedNode = processNode(child);
|
|
27561
|
+
if (processedNode) {
|
|
27562
|
+
if (Array.isArray(processedNode)) {
|
|
27563
|
+
processedNode.forEach((node2) => paragraphNode.append(node2));
|
|
27564
|
+
} else {
|
|
27565
|
+
paragraphNode.append(processedNode);
|
|
27566
|
+
}
|
|
27567
|
+
}
|
|
27568
|
+
});
|
|
27569
|
+
return paragraphNode;
|
|
27570
|
+
}
|
|
27571
|
+
const nodes = [];
|
|
27572
|
+
Array.from(element.childNodes).forEach((child) => {
|
|
27573
|
+
const processedNode = processNode(child);
|
|
27574
|
+
if (processedNode) {
|
|
27575
|
+
if (Array.isArray(processedNode)) {
|
|
27576
|
+
nodes.push(...processedNode);
|
|
27577
|
+
} else {
|
|
27578
|
+
nodes.push(processedNode);
|
|
27579
|
+
}
|
|
27580
|
+
}
|
|
27581
|
+
});
|
|
27582
|
+
return nodes;
|
|
27583
|
+
}
|
|
27584
|
+
return null;
|
|
27585
|
+
};
|
|
27586
|
+
const processedNodes = processNode(tempDiv);
|
|
27587
|
+
if (processedNodes) {
|
|
27588
|
+
if (Array.isArray(processedNodes)) {
|
|
27589
|
+
selection.insertNodes(processedNodes);
|
|
27590
|
+
} else {
|
|
27591
|
+
selection.insertNodes([processedNodes]);
|
|
27592
|
+
}
|
|
27593
|
+
}
|
|
27594
|
+
}
|
|
27595
|
+
});
|
|
27596
|
+
};
|
|
27597
|
+
const handleMarkdownPaste = (text) => {
|
|
27598
|
+
editor.update(() => {
|
|
27599
|
+
const selection = $getSelection();
|
|
27600
|
+
if ($isRangeSelection(selection)) {
|
|
27601
|
+
const lines = text.split("\n");
|
|
27602
|
+
const nodes = [];
|
|
27603
|
+
lines.forEach((line) => {
|
|
27604
|
+
const headingMatch = line.match(/^(#{1,6})\s+(.+)$/);
|
|
27605
|
+
if (headingMatch) {
|
|
27606
|
+
const level = headingMatch[1].length;
|
|
27607
|
+
const content = headingMatch[2];
|
|
27608
|
+
const headingNode = $createHeadingNode(
|
|
27609
|
+
`h${level}`
|
|
27610
|
+
);
|
|
27611
|
+
headingNode.append($createTextNode(content));
|
|
27612
|
+
nodes.push(headingNode);
|
|
27613
|
+
return;
|
|
27614
|
+
}
|
|
27615
|
+
const bulletMatch = line.match(/^-\s+(.+)$/);
|
|
27616
|
+
if (bulletMatch) {
|
|
27617
|
+
const listNode = $createListNode("bullet");
|
|
27618
|
+
const listItemNode = $createListItemNode();
|
|
27619
|
+
listItemNode.append($createTextNode(bulletMatch[1]));
|
|
27620
|
+
listNode.append(listItemNode);
|
|
27621
|
+
nodes.push(listNode);
|
|
27622
|
+
return;
|
|
27623
|
+
}
|
|
27624
|
+
const numberedMatch = line.match(/^\d+\.\s+(.+)$/);
|
|
27625
|
+
if (numberedMatch) {
|
|
27626
|
+
const listNode = $createListNode("number");
|
|
27627
|
+
const listItemNode = $createListItemNode();
|
|
27628
|
+
listItemNode.append($createTextNode(numberedMatch[1]));
|
|
27629
|
+
listNode.append(listItemNode);
|
|
27630
|
+
nodes.push(listNode);
|
|
27631
|
+
return;
|
|
27632
|
+
}
|
|
27633
|
+
const textNode = $createTextNode(line);
|
|
27634
|
+
if (line.includes("**") || line.includes("__")) {
|
|
27635
|
+
textNode.setFormat("bold");
|
|
27636
|
+
}
|
|
27637
|
+
if (line.includes("*") || line.includes("_")) {
|
|
27638
|
+
textNode.setFormat("italic");
|
|
27639
|
+
}
|
|
27640
|
+
if (line.includes("***") || line.includes("___")) {
|
|
27641
|
+
textNode.setFormat("bold");
|
|
27642
|
+
textNode.setFormat("italic");
|
|
27643
|
+
}
|
|
27644
|
+
nodes.push(textNode);
|
|
27645
|
+
});
|
|
27646
|
+
selection.insertNodes(nodes);
|
|
27647
|
+
}
|
|
27648
|
+
});
|
|
27649
|
+
};
|
|
27650
|
+
return null;
|
|
27651
|
+
}
|
|
26935
27652
|
function useModal() {
|
|
26936
27653
|
const [modalContent, setModalContent] = useState$1(null);
|
|
26937
27654
|
const onClose = useCallback(() => {
|
|
@@ -27477,8 +28194,79 @@ function TableActionMenu({
|
|
|
27477
28194
|
for (let i2 = 0; i2 < selectionCounts.columns; i2++) {
|
|
27478
28195
|
$insertTableColumn__EXPERIMENTAL(shouldInsertAfter);
|
|
27479
28196
|
}
|
|
28197
|
+
const selection = $getSelection();
|
|
28198
|
+
if ($isRangeSelection(selection) || $isTableSelection(selection)) {
|
|
28199
|
+
const [cell] = $getNodeTriplet(selection.anchor);
|
|
28200
|
+
if ($isTableCellNode(cell)) {
|
|
28201
|
+
const tableNode = $getTableNodeFromLexicalNodeOrThrow(cell);
|
|
28202
|
+
const rows = tableNode.getChildren();
|
|
28203
|
+
if (rows.length > 0 && $isTableRowNode(rows[0])) {
|
|
28204
|
+
const firstRow = rows[0];
|
|
28205
|
+
const firstRowCells = firstRow.getChildren();
|
|
28206
|
+
if (firstRowCells.length > 0 && $isTableCellNode(firstRowCells[0])) {
|
|
28207
|
+
const firstCell = firstRowCells[0];
|
|
28208
|
+
const hasColumnHeaders = (firstCell.getHeaderStyles() & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN;
|
|
28209
|
+
if (hasColumnHeaders) {
|
|
28210
|
+
const headerBackgroundColor = firstCell.getBackgroundColor();
|
|
28211
|
+
for (let i2 = 0; i2 < selectionCounts.columns; i2++) {
|
|
28212
|
+
const newHeaderCellIndex = firstRowCells.length - 1 - i2;
|
|
28213
|
+
if (newHeaderCellIndex >= 0) {
|
|
28214
|
+
const newHeaderCell = firstRowCells[newHeaderCellIndex];
|
|
28215
|
+
if ($isTableCellNode(newHeaderCell)) {
|
|
28216
|
+
newHeaderCell.setHeaderStyles(TableCellHeaderStates.COLUMN);
|
|
28217
|
+
if (headerBackgroundColor) {
|
|
28218
|
+
newHeaderCell.setBackgroundColor(headerBackgroundColor);
|
|
28219
|
+
}
|
|
28220
|
+
}
|
|
28221
|
+
}
|
|
28222
|
+
}
|
|
28223
|
+
}
|
|
28224
|
+
}
|
|
28225
|
+
}
|
|
28226
|
+
}
|
|
28227
|
+
}
|
|
27480
28228
|
onClose();
|
|
27481
28229
|
});
|
|
28230
|
+
requestAnimationFrame(() => {
|
|
28231
|
+
const applyHeaderStyles = () => {
|
|
28232
|
+
const rootElement = editor.getRootElement();
|
|
28233
|
+
if (!rootElement)
|
|
28234
|
+
return false;
|
|
28235
|
+
const tables = rootElement.querySelectorAll("table");
|
|
28236
|
+
tables.forEach((table) => {
|
|
28237
|
+
const rows = table.querySelectorAll("tr");
|
|
28238
|
+
if (rows.length > 0) {
|
|
28239
|
+
const firstRow = rows[0];
|
|
28240
|
+
const cells = firstRow.querySelectorAll("th, td");
|
|
28241
|
+
if (cells.length > 1) {
|
|
28242
|
+
const firstHeaderCell = cells[0];
|
|
28243
|
+
const headerColor = firstHeaderCell.getAttribute("data-header-color");
|
|
28244
|
+
const textColor = firstHeaderCell.getAttribute("data-text-color");
|
|
28245
|
+
if (headerColor && textColor) {
|
|
28246
|
+
for (let i2 = 0; i2 < selectionCounts.columns; i2++) {
|
|
28247
|
+
const cellIndex = cells.length - 1 - i2;
|
|
28248
|
+
if (cellIndex >= 0) {
|
|
28249
|
+
const newCell = cells[cellIndex];
|
|
28250
|
+
newCell.setAttribute("data-header-color", headerColor);
|
|
28251
|
+
newCell.setAttribute("data-text-color", textColor);
|
|
28252
|
+
newCell.style.setProperty("background-color", headerColor, "important");
|
|
28253
|
+
newCell.style.setProperty("color", textColor, "important");
|
|
28254
|
+
newCell.style.setProperty("padding", "8px", "important");
|
|
28255
|
+
newCell.style.setProperty("border", "1px solid #ddd", "important");
|
|
28256
|
+
newCell.style.setProperty("font-weight", "bold", "important");
|
|
28257
|
+
newCell.style.setProperty("white-space", "nowrap", "important");
|
|
28258
|
+
}
|
|
28259
|
+
}
|
|
28260
|
+
}
|
|
28261
|
+
}
|
|
28262
|
+
}
|
|
28263
|
+
});
|
|
28264
|
+
return true;
|
|
28265
|
+
};
|
|
28266
|
+
if (!applyHeaderStyles()) {
|
|
28267
|
+
setTimeout(applyHeaderStyles, 100);
|
|
28268
|
+
}
|
|
28269
|
+
});
|
|
27482
28270
|
},
|
|
27483
28271
|
[editor, onClose, selectionCounts.columns]
|
|
27484
28272
|
);
|
|
@@ -28475,9 +29263,72 @@ function TableHoverActionsContainer({
|
|
|
28475
29263
|
} else {
|
|
28476
29264
|
$insertTableColumn__EXPERIMENTAL();
|
|
28477
29265
|
setShownColumn(false);
|
|
29266
|
+
const tableCellNode = $getNearestNodeFromDOMNode(tableCellDOMNodeRef.current);
|
|
29267
|
+
if ($isTableCellNode(tableCellNode)) {
|
|
29268
|
+
const tableNode = $findMatchingParent(
|
|
29269
|
+
tableCellNode,
|
|
29270
|
+
(node) => $isTableNode(node)
|
|
29271
|
+
);
|
|
29272
|
+
if ($isTableNode(tableNode)) {
|
|
29273
|
+
const rows = tableNode.getChildren();
|
|
29274
|
+
if (rows.length > 0) {
|
|
29275
|
+
const firstRow = rows[0];
|
|
29276
|
+
const firstRowCells = firstRow.getChildren();
|
|
29277
|
+
if (firstRowCells.length > 0) {
|
|
29278
|
+
const firstCell = firstRowCells[0];
|
|
29279
|
+
const hasColumnHeaders = (firstCell.getHeaderStyles() & TableCellHeaderStates.COLUMN) === TableCellHeaderStates.COLUMN;
|
|
29280
|
+
if (hasColumnHeaders) {
|
|
29281
|
+
const newHeaderCell = firstRowCells[firstRowCells.length - 1];
|
|
29282
|
+
newHeaderCell.setHeaderStyles(TableCellHeaderStates.COLUMN);
|
|
29283
|
+
const headerBackgroundColor = firstCell.getBackgroundColor();
|
|
29284
|
+
if (headerBackgroundColor) {
|
|
29285
|
+
newHeaderCell.setBackgroundColor(headerBackgroundColor);
|
|
29286
|
+
}
|
|
29287
|
+
}
|
|
29288
|
+
}
|
|
29289
|
+
}
|
|
29290
|
+
}
|
|
29291
|
+
}
|
|
28478
29292
|
}
|
|
28479
29293
|
}
|
|
28480
29294
|
});
|
|
29295
|
+
if (!insertRow) {
|
|
29296
|
+
requestAnimationFrame(() => {
|
|
29297
|
+
const applyHeaderStyles = () => {
|
|
29298
|
+
const rootElement = editor.getRootElement();
|
|
29299
|
+
if (!rootElement)
|
|
29300
|
+
return false;
|
|
29301
|
+
const tables = rootElement.querySelectorAll("table");
|
|
29302
|
+
tables.forEach((table) => {
|
|
29303
|
+
const rows = table.querySelectorAll("tr");
|
|
29304
|
+
if (rows.length > 0) {
|
|
29305
|
+
const firstRow = rows[0];
|
|
29306
|
+
const cells = firstRow.querySelectorAll("th, td");
|
|
29307
|
+
if (cells.length > 1) {
|
|
29308
|
+
const firstHeaderCell = cells[0];
|
|
29309
|
+
const headerColor = firstHeaderCell.getAttribute("data-header-color");
|
|
29310
|
+
const textColor = firstHeaderCell.getAttribute("data-text-color");
|
|
29311
|
+
if (headerColor && textColor) {
|
|
29312
|
+
const lastCell = cells[cells.length - 1];
|
|
29313
|
+
lastCell.setAttribute("data-header-color", headerColor);
|
|
29314
|
+
lastCell.setAttribute("data-text-color", textColor);
|
|
29315
|
+
lastCell.style.setProperty("background-color", headerColor, "important");
|
|
29316
|
+
lastCell.style.setProperty("color", textColor, "important");
|
|
29317
|
+
lastCell.style.setProperty("padding", "8px", "important");
|
|
29318
|
+
lastCell.style.setProperty("border", "1px solid #ddd", "important");
|
|
29319
|
+
lastCell.style.setProperty("font-weight", "bold", "important");
|
|
29320
|
+
lastCell.style.setProperty("white-space", "nowrap", "important");
|
|
29321
|
+
}
|
|
29322
|
+
}
|
|
29323
|
+
}
|
|
29324
|
+
});
|
|
29325
|
+
return true;
|
|
29326
|
+
};
|
|
29327
|
+
if (!applyHeaderStyles()) {
|
|
29328
|
+
setTimeout(applyHeaderStyles, 100);
|
|
29329
|
+
}
|
|
29330
|
+
});
|
|
29331
|
+
}
|
|
28481
29332
|
};
|
|
28482
29333
|
if (!isEditable) {
|
|
28483
29334
|
return null;
|
|
@@ -28528,6 +29379,46 @@ function TableHoverActionsPlugin({
|
|
|
28528
29379
|
anchorElem
|
|
28529
29380
|
) : null;
|
|
28530
29381
|
}
|
|
29382
|
+
function getOptionMeta(label) {
|
|
29383
|
+
const lower = label.toLowerCase();
|
|
29384
|
+
if (lower.startsWith("paragraph")) {
|
|
29385
|
+
return { icon: /* @__PURE__ */ jsx(Type, { className: "cteditor-size-4" }), description: "Start a new paragraph", shortcut: "P" };
|
|
29386
|
+
}
|
|
29387
|
+
if (lower.includes("heading 1")) {
|
|
29388
|
+
return { icon: /* @__PURE__ */ jsx(Heading1, { className: "cteditor-size-4" }), description: "Large section title", shortcut: "H1" };
|
|
29389
|
+
}
|
|
29390
|
+
if (lower.includes("heading 2")) {
|
|
29391
|
+
return { icon: /* @__PURE__ */ jsx(Heading2, { className: "cteditor-size-4" }), description: "Section heading", shortcut: "H2" };
|
|
29392
|
+
}
|
|
29393
|
+
if (lower.includes("heading 3")) {
|
|
29394
|
+
return { icon: /* @__PURE__ */ jsx(Heading3, { className: "cteditor-size-4" }), description: "Subsection heading", shortcut: "H3" };
|
|
29395
|
+
}
|
|
29396
|
+
if (lower.includes("bullet")) {
|
|
29397
|
+
return { icon: /* @__PURE__ */ jsx(List$1, { className: "cteditor-size-4" }), description: "Create a bulleted list", shortcut: "•" };
|
|
29398
|
+
}
|
|
29399
|
+
if (lower.includes("numbered")) {
|
|
29400
|
+
return { icon: /* @__PURE__ */ jsx(ListOrdered, { className: "cteditor-size-4" }), description: "Create a numbered list", shortcut: "1." };
|
|
29401
|
+
}
|
|
29402
|
+
if (lower.includes("todo")) {
|
|
29403
|
+
return { icon: /* @__PURE__ */ jsx(ListChecks, { className: "cteditor-size-4" }), description: "Create a checklist", shortcut: "[ ]" };
|
|
29404
|
+
}
|
|
29405
|
+
if (lower.includes("image")) {
|
|
29406
|
+
return { icon: /* @__PURE__ */ jsx(Image$2, { className: "cteditor-size-4" }), description: "Insert an image", shortcut: "Img" };
|
|
29407
|
+
}
|
|
29408
|
+
if (lower.includes("video")) {
|
|
29409
|
+
return { icon: /* @__PURE__ */ jsx(Video, { className: "cteditor-size-4" }), description: "Embed a video", shortcut: "Vid" };
|
|
29410
|
+
}
|
|
29411
|
+
if (lower.includes("align left")) {
|
|
29412
|
+
return { icon: /* @__PURE__ */ jsx(AlignLeft, { className: "cteditor-size-4" }), description: "Align text left" };
|
|
29413
|
+
}
|
|
29414
|
+
if (lower.includes("align center")) {
|
|
29415
|
+
return { icon: /* @__PURE__ */ jsx(AlignCenter, { className: "cteditor-size-4" }), description: "Align text center" };
|
|
29416
|
+
}
|
|
29417
|
+
if (lower.includes("align right")) {
|
|
29418
|
+
return { icon: /* @__PURE__ */ jsx(AlignRight, { className: "cteditor-size-4" }), description: "Align text right" };
|
|
29419
|
+
}
|
|
29420
|
+
return { icon: /* @__PURE__ */ jsx(Type, { className: "cteditor-size-4" }) };
|
|
29421
|
+
}
|
|
28531
29422
|
class SlashMenuOption extends MenuOption {
|
|
28532
29423
|
constructor(label, onSelect) {
|
|
28533
29424
|
super(label);
|
|
@@ -28544,22 +29435,26 @@ function SlashMenuItem({
|
|
|
28544
29435
|
onMouseEnter,
|
|
28545
29436
|
option
|
|
28546
29437
|
}) {
|
|
28547
|
-
|
|
28548
|
-
|
|
28549
|
-
className += " selected";
|
|
28550
|
-
}
|
|
28551
|
-
return /* @__PURE__ */ jsx(
|
|
29438
|
+
const meta = getOptionMeta(option.label);
|
|
29439
|
+
return /* @__PURE__ */ jsxs(
|
|
28552
29440
|
"li",
|
|
28553
29441
|
{
|
|
28554
29442
|
tabIndex: -1,
|
|
28555
|
-
className,
|
|
29443
|
+
className: (isSelected ? "cteditor-bg-primary/10 cteditor-border-primary/40 cteditor-shadow-md " : "hover:cteditor-bg-accent/50 hover:cteditor-border-primary/30 hover:cteditor-shadow ") + "cteditor-group cteditor-flex cteditor-items-center cteditor-gap-3 cteditor-px-3 cteditor-py-2 cteditor-rounded-xl cteditor-transition-all cteditor-duration-200 cteditor-cursor-pointer cteditor-border cteditor-border-border hover:cteditor-translate-x-[1px]",
|
|
28556
29444
|
ref: option.setRefElement,
|
|
28557
29445
|
role: "option",
|
|
28558
29446
|
"aria-selected": isSelected,
|
|
28559
29447
|
id: "typeahead-item-" + index2,
|
|
28560
29448
|
onMouseEnter,
|
|
28561
29449
|
onClick,
|
|
28562
|
-
children:
|
|
29450
|
+
children: [
|
|
29451
|
+
/* @__PURE__ */ jsx("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-center cteditor-rounded-lg cteditor-h-8 cteditor-w-8 cteditor-text-primary cteditor-bg-gradient-to-br cteditor-from-primary/10 cteditor-to-accent/10 group-hover:cteditor-from-primary/20 group-hover:cteditor-to-accent/20", children: meta.icon }),
|
|
29452
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-flex-col cteditor-gap-0.5 cteditor-min-w-0", children: [
|
|
29453
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-text-sm cteditor-font-semibold cteditor-text-foreground cteditor-truncate", children: option.label }),
|
|
29454
|
+
meta.description && /* @__PURE__ */ jsx("span", { className: "cteditor-text-xs cteditor-text-muted-foreground cteditor-truncate", children: meta.description })
|
|
29455
|
+
] }),
|
|
29456
|
+
meta.shortcut && /* @__PURE__ */ jsx("span", { className: "cteditor-ml-auto cteditor-text-[10px] cteditor-text-muted-foreground cteditor-border cteditor-border-border cteditor-rounded-md cteditor-px-1.5 cteditor-py-0.5 cteditor-bg-foreground/5", children: meta.shortcut })
|
|
29457
|
+
]
|
|
28563
29458
|
},
|
|
28564
29459
|
option.key
|
|
28565
29460
|
);
|
|
@@ -28567,6 +29462,10 @@ function SlashMenuItem({
|
|
|
28567
29462
|
function SlashCommandPlugin() {
|
|
28568
29463
|
const [editor] = useLexicalComposerContext();
|
|
28569
29464
|
const [queryString, setQueryString] = useState$1(null);
|
|
29465
|
+
const menuRef = useRef(null);
|
|
29466
|
+
const [menuPosition, setMenuPosition] = useState$1({ left: 0 });
|
|
29467
|
+
const anchorRef = useRef(null);
|
|
29468
|
+
const [isMenuOpen, setIsMenuOpen] = useState$1(false);
|
|
28570
29469
|
const triggerFn = useBasicTypeaheadTriggerMatch("/", { minLength: 0 });
|
|
28571
29470
|
const makeBlock = useCallback((cb) => {
|
|
28572
29471
|
editor.update(() => {
|
|
@@ -28653,9 +29552,55 @@ function SlashCommandPlugin() {
|
|
|
28653
29552
|
}
|
|
28654
29553
|
});
|
|
28655
29554
|
closeMenu();
|
|
29555
|
+
setIsMenuOpen(false);
|
|
28656
29556
|
},
|
|
28657
29557
|
[editor]
|
|
28658
29558
|
);
|
|
29559
|
+
useEffect$1(() => {
|
|
29560
|
+
if (!isMenuOpen) {
|
|
29561
|
+
return;
|
|
29562
|
+
}
|
|
29563
|
+
const menu = menuRef.current;
|
|
29564
|
+
const anchor = anchorRef.current;
|
|
29565
|
+
if (!menu || !anchor) {
|
|
29566
|
+
return;
|
|
29567
|
+
}
|
|
29568
|
+
const updatePosition = () => {
|
|
29569
|
+
const menuRect = menu.getBoundingClientRect();
|
|
29570
|
+
const viewportHeight = window.innerHeight;
|
|
29571
|
+
const viewportWidth = window.innerWidth;
|
|
29572
|
+
const anchorRect = anchor.getBoundingClientRect();
|
|
29573
|
+
const spaceBelow = viewportHeight - anchorRect.bottom;
|
|
29574
|
+
const spaceAbove = anchorRect.top;
|
|
29575
|
+
const menuHeight = menuRect.height || 240;
|
|
29576
|
+
const menuWidth = menuRect.width || 288;
|
|
29577
|
+
let newPosition = { left: anchorRect.left };
|
|
29578
|
+
if (spaceBelow >= menuHeight || spaceBelow >= spaceAbove) {
|
|
29579
|
+
newPosition.top = anchorRect.bottom + 4;
|
|
29580
|
+
} else {
|
|
29581
|
+
newPosition.bottom = viewportHeight - anchorRect.top + 4;
|
|
29582
|
+
}
|
|
29583
|
+
if (anchorRect.left + menuWidth > viewportWidth) {
|
|
29584
|
+
newPosition.left = Math.max(8, viewportWidth - menuWidth - 8);
|
|
29585
|
+
} else {
|
|
29586
|
+
newPosition.left = Math.max(8, anchorRect.left);
|
|
29587
|
+
}
|
|
29588
|
+
setMenuPosition((prev) => {
|
|
29589
|
+
if (prev.top === newPosition.top && prev.bottom === newPosition.bottom && prev.left === newPosition.left) {
|
|
29590
|
+
return prev;
|
|
29591
|
+
}
|
|
29592
|
+
return newPosition;
|
|
29593
|
+
});
|
|
29594
|
+
};
|
|
29595
|
+
const timeoutId = setTimeout(updatePosition, 0);
|
|
29596
|
+
window.addEventListener("scroll", updatePosition, true);
|
|
29597
|
+
window.addEventListener("resize", updatePosition);
|
|
29598
|
+
return () => {
|
|
29599
|
+
clearTimeout(timeoutId);
|
|
29600
|
+
window.removeEventListener("scroll", updatePosition, true);
|
|
29601
|
+
window.removeEventListener("resize", updatePosition);
|
|
29602
|
+
};
|
|
29603
|
+
}, [isMenuOpen]);
|
|
28659
29604
|
return /* @__PURE__ */ jsx(
|
|
28660
29605
|
LexicalTypeaheadMenuPlugin,
|
|
28661
29606
|
{
|
|
@@ -28663,27 +29608,54 @@ function SlashCommandPlugin() {
|
|
|
28663
29608
|
onSelectOption,
|
|
28664
29609
|
triggerFn,
|
|
28665
29610
|
options,
|
|
28666
|
-
menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) =>
|
|
28667
|
-
|
|
28668
|
-
|
|
28669
|
-
|
|
28670
|
-
|
|
28671
|
-
|
|
28672
|
-
|
|
28673
|
-
|
|
28674
|
-
|
|
28675
|
-
|
|
28676
|
-
|
|
28677
|
-
|
|
28678
|
-
|
|
28679
|
-
|
|
28680
|
-
|
|
28681
|
-
|
|
28682
|
-
|
|
28683
|
-
|
|
28684
|
-
|
|
28685
|
-
|
|
28686
|
-
|
|
29611
|
+
menuRenderFn: (anchorElementRef, { selectedIndex, selectOptionAndCleanUp, setHighlightedIndex }) => {
|
|
29612
|
+
anchorRef.current = anchorElementRef.current;
|
|
29613
|
+
if (anchorElementRef.current && !isMenuOpen) {
|
|
29614
|
+
setIsMenuOpen(true);
|
|
29615
|
+
} else if (!anchorElementRef.current && isMenuOpen) {
|
|
29616
|
+
setIsMenuOpen(false);
|
|
29617
|
+
}
|
|
29618
|
+
return anchorElementRef.current ? ReactDOM.createPortal(
|
|
29619
|
+
/* @__PURE__ */ jsxs(
|
|
29620
|
+
"div",
|
|
29621
|
+
{
|
|
29622
|
+
ref: menuRef,
|
|
29623
|
+
className: "cteditor-w-72 cteditor-max-h-60 cteditor-overflow-y-auto no-scrollbar cteditor-backdrop-blur-md cteditor-shadow-xl cteditor-rounded-lg cteditor-border cteditor-border-border cteditor-p-1.5 cteditor-bg-background cteditor-z-50",
|
|
29624
|
+
style: {
|
|
29625
|
+
position: "fixed",
|
|
29626
|
+
top: menuPosition.top,
|
|
29627
|
+
bottom: menuPosition.bottom,
|
|
29628
|
+
left: menuPosition.left
|
|
29629
|
+
},
|
|
29630
|
+
children: [
|
|
29631
|
+
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-justify-between cteditor-px-2 cteditor-py-1 cteditor-text-[11px] cteditor-text-muted-foreground", children: [
|
|
29632
|
+
/* @__PURE__ */ jsx("span", { children: queryString ? "Search results" : "Quick actions" }),
|
|
29633
|
+
/* @__PURE__ */ jsx("span", { className: "cteditor-hidden sm:cteditor-inline", children: "Type to filter" })
|
|
29634
|
+
] }),
|
|
29635
|
+
options.length > 0 ? /* @__PURE__ */ jsx("ul", { className: "cteditor-space-y-1", children: options.map((option, i2) => /* @__PURE__ */ jsx(
|
|
29636
|
+
SlashMenuItem,
|
|
29637
|
+
{
|
|
29638
|
+
index: i2,
|
|
29639
|
+
isSelected: selectedIndex === i2,
|
|
29640
|
+
onClick: () => {
|
|
29641
|
+
setHighlightedIndex(i2);
|
|
29642
|
+
selectOptionAndCleanUp(option);
|
|
29643
|
+
},
|
|
29644
|
+
onMouseEnter: () => {
|
|
29645
|
+
setHighlightedIndex(i2);
|
|
29646
|
+
},
|
|
29647
|
+
option
|
|
29648
|
+
},
|
|
29649
|
+
option.key
|
|
29650
|
+
)) }) : /* @__PURE__ */ jsx("div", { className: "cteditor-text-[11px] cteditor-text-muted-foreground cteditor-px-3 cteditor-py-2", children: "No results" })
|
|
29651
|
+
]
|
|
29652
|
+
}
|
|
29653
|
+
),
|
|
29654
|
+
anchorElementRef.current
|
|
29655
|
+
) : null;
|
|
29656
|
+
}
|
|
29657
|
+
}
|
|
29658
|
+
);
|
|
28687
29659
|
}
|
|
28688
29660
|
const WordCountPlugin = () => {
|
|
28689
29661
|
const [editor] = useLexicalComposerContext();
|
|
@@ -28733,402 +29705,14 @@ const WordCountPlugin = () => {
|
|
|
28733
29705
|
}
|
|
28734
29706
|
);
|
|
28735
29707
|
};
|
|
28736
|
-
const GrammarCheckPlugin$1 = "";
|
|
28737
|
-
class GrammarCheckService {
|
|
28738
|
-
constructor() {
|
|
28739
|
-
__publicField(this, "cache", /* @__PURE__ */ new Map());
|
|
28740
|
-
__publicField(this, "apiEndpoint");
|
|
28741
|
-
__publicField(this, "pendingRequest", null);
|
|
28742
|
-
this.apiEndpoint = "https://api.cteditor.com/api/ai/process";
|
|
28743
|
-
}
|
|
28744
|
-
async check(text) {
|
|
28745
|
-
if (!text || text.trim().length < 3) {
|
|
28746
|
-
return [];
|
|
28747
|
-
}
|
|
28748
|
-
const cacheKey = text.trim();
|
|
28749
|
-
if (this.cache.has(cacheKey)) {
|
|
28750
|
-
return this.cache.get(cacheKey);
|
|
28751
|
-
}
|
|
28752
|
-
if (this.pendingRequest) {
|
|
28753
|
-
return this.pendingRequest;
|
|
28754
|
-
}
|
|
28755
|
-
this.pendingRequest = this.executeCheck(text);
|
|
28756
|
-
try {
|
|
28757
|
-
const result = await this.pendingRequest;
|
|
28758
|
-
return result;
|
|
28759
|
-
} finally {
|
|
28760
|
-
this.pendingRequest = null;
|
|
28761
|
-
}
|
|
28762
|
-
}
|
|
28763
|
-
async executeCheck(text) {
|
|
28764
|
-
var _a, _b, _c, _d, _e, _f;
|
|
28765
|
-
try {
|
|
28766
|
-
const response = await fetch(this.apiEndpoint, {
|
|
28767
|
-
method: "POST",
|
|
28768
|
-
headers: { "Content-Type": "application/json" },
|
|
28769
|
-
body: JSON.stringify({ text: text.trim(), maxSuggestions: 3 }),
|
|
28770
|
-
signal: AbortSignal.timeout(1e4)
|
|
28771
|
-
});
|
|
28772
|
-
if (!response.ok) {
|
|
28773
|
-
console.error("❌ GrammarCheck: API error:", response.status);
|
|
28774
|
-
return [];
|
|
28775
|
-
}
|
|
28776
|
-
const result = await response.json();
|
|
28777
|
-
const foundErrors = [];
|
|
28778
|
-
if ((_c = (_b = (_a = result.data) == null ? void 0 : _a.corrections) == null ? void 0 : _b.spelling) == null ? void 0 : _c.errors) {
|
|
28779
|
-
result.data.corrections.spelling.errors.forEach((err, idx) => {
|
|
28780
|
-
foundErrors.push({
|
|
28781
|
-
type: "spelling",
|
|
28782
|
-
original: err.original,
|
|
28783
|
-
suggestions: err.suggestions || [],
|
|
28784
|
-
index: idx
|
|
28785
|
-
});
|
|
28786
|
-
});
|
|
28787
|
-
}
|
|
28788
|
-
if ((_f = (_e = (_d = result.data) == null ? void 0 : _d.corrections) == null ? void 0 : _e.grammar) == null ? void 0 : _f.errors) {
|
|
28789
|
-
result.data.corrections.grammar.errors.forEach((err, idx) => {
|
|
28790
|
-
foundErrors.push({
|
|
28791
|
-
type: "grammar",
|
|
28792
|
-
original: err.original || text,
|
|
28793
|
-
suggestions: [err.suggestion],
|
|
28794
|
-
index: foundErrors.length + idx,
|
|
28795
|
-
issue: err.issue
|
|
28796
|
-
});
|
|
28797
|
-
});
|
|
28798
|
-
}
|
|
28799
|
-
this.cache.set(text.trim(), foundErrors);
|
|
28800
|
-
if (this.cache.size > 30) {
|
|
28801
|
-
const firstKey = this.cache.keys().next().value;
|
|
28802
|
-
if (firstKey) {
|
|
28803
|
-
this.cache.delete(firstKey);
|
|
28804
|
-
}
|
|
28805
|
-
}
|
|
28806
|
-
return foundErrors;
|
|
28807
|
-
} catch (error) {
|
|
28808
|
-
console.error("❌ GrammarCheck: Check failed:", error);
|
|
28809
|
-
return [];
|
|
28810
|
-
}
|
|
28811
|
-
}
|
|
28812
|
-
}
|
|
28813
|
-
function GrammarCheckPlugin() {
|
|
28814
|
-
const [editor] = useLexicalComposerContext();
|
|
28815
|
-
const { updateToolbarState } = useToolbarState();
|
|
28816
|
-
const [errors, setErrors] = useState$1([]);
|
|
28817
|
-
const [tooltip, setTooltip] = useState$1(null);
|
|
28818
|
-
const [userDismissed, setUserDismissed] = useState$1(false);
|
|
28819
|
-
const grammarService = useRef(new GrammarCheckService());
|
|
28820
|
-
const checkTimeout = useRef();
|
|
28821
|
-
const lastCheckedText = useRef("");
|
|
28822
|
-
const highlightElementsRef = useRef([]);
|
|
28823
|
-
const checkGrammar = useCallback(async () => {
|
|
28824
|
-
const text = editor.getEditorState().read(() => $getRoot().getTextContent());
|
|
28825
|
-
if (text === lastCheckedText.current) {
|
|
28826
|
-
return;
|
|
28827
|
-
}
|
|
28828
|
-
if (Math.abs(text.length - lastCheckedText.current.length) > 20) {
|
|
28829
|
-
setUserDismissed(false);
|
|
28830
|
-
}
|
|
28831
|
-
lastCheckedText.current = text;
|
|
28832
|
-
if (!text || text.trim().length < 3) {
|
|
28833
|
-
setErrors([]);
|
|
28834
|
-
return;
|
|
28835
|
-
}
|
|
28836
|
-
const foundErrors = await grammarService.current.check(text);
|
|
28837
|
-
setErrors(foundErrors);
|
|
28838
|
-
}, [editor]);
|
|
28839
|
-
useEffect$1(() => {
|
|
28840
|
-
const unregister = editor.registerUpdateListener(() => {
|
|
28841
|
-
clearTimeout(checkTimeout.current);
|
|
28842
|
-
checkTimeout.current = window.setTimeout(checkGrammar, 2e3);
|
|
28843
|
-
});
|
|
28844
|
-
return () => {
|
|
28845
|
-
unregister();
|
|
28846
|
-
clearTimeout(checkTimeout.current);
|
|
28847
|
-
};
|
|
28848
|
-
}, [editor, checkGrammar]);
|
|
28849
|
-
useEffect$1(() => {
|
|
28850
|
-
highlightElementsRef.current.forEach((el) => {
|
|
28851
|
-
el.classList.remove("spelling-error", "grammar-error");
|
|
28852
|
-
});
|
|
28853
|
-
highlightElementsRef.current = [];
|
|
28854
|
-
if (errors.length === 0 || userDismissed)
|
|
28855
|
-
return;
|
|
28856
|
-
const timeoutId = setTimeout(() => {
|
|
28857
|
-
const editorElement = document.querySelector(".ContentEditable__root");
|
|
28858
|
-
if (!editorElement)
|
|
28859
|
-
return;
|
|
28860
|
-
const walker = document.createTreeWalker(
|
|
28861
|
-
editorElement,
|
|
28862
|
-
NodeFilter.SHOW_TEXT,
|
|
28863
|
-
null
|
|
28864
|
-
);
|
|
28865
|
-
const textNodes = [];
|
|
28866
|
-
let node;
|
|
28867
|
-
while (node = walker.nextNode()) {
|
|
28868
|
-
textNodes.push(node);
|
|
28869
|
-
}
|
|
28870
|
-
errors.forEach((error) => {
|
|
28871
|
-
textNodes.forEach((textNode) => {
|
|
28872
|
-
const nodeText = textNode.textContent || "";
|
|
28873
|
-
const errorIndex = nodeText.toLowerCase().indexOf(error.original.toLowerCase());
|
|
28874
|
-
if (errorIndex !== -1 && textNode.parentElement) {
|
|
28875
|
-
const className = error.type === "spelling" ? "spelling-error" : "grammar-error";
|
|
28876
|
-
if (textNode.parentElement.tagName === "SPAN") {
|
|
28877
|
-
textNode.parentElement.classList.add(className);
|
|
28878
|
-
highlightElementsRef.current.push(textNode.parentElement);
|
|
28879
|
-
} else if (textNode.parentElement) {
|
|
28880
|
-
const range = document.createRange();
|
|
28881
|
-
range.setStart(textNode, errorIndex);
|
|
28882
|
-
range.setEnd(textNode, Math.min(errorIndex + error.original.length, nodeText.length));
|
|
28883
|
-
const span = document.createElement("span");
|
|
28884
|
-
span.className = className;
|
|
28885
|
-
span.setAttribute("data-error-type", error.type);
|
|
28886
|
-
try {
|
|
28887
|
-
range.surroundContents(span);
|
|
28888
|
-
highlightElementsRef.current.push(span);
|
|
28889
|
-
} catch (e) {
|
|
28890
|
-
if (textNode.parentElement) {
|
|
28891
|
-
textNode.parentElement.classList.add(className);
|
|
28892
|
-
highlightElementsRef.current.push(textNode.parentElement);
|
|
28893
|
-
}
|
|
28894
|
-
}
|
|
28895
|
-
}
|
|
28896
|
-
}
|
|
28897
|
-
});
|
|
28898
|
-
});
|
|
28899
|
-
}, 100);
|
|
28900
|
-
return () => clearTimeout(timeoutId);
|
|
28901
|
-
}, [errors, userDismissed]);
|
|
28902
|
-
const getWordAtPoint = useCallback((x2, y2) => {
|
|
28903
|
-
try {
|
|
28904
|
-
let range = null;
|
|
28905
|
-
if (document.caretRangeFromPoint) {
|
|
28906
|
-
range = document.caretRangeFromPoint(x2, y2);
|
|
28907
|
-
} else if (document.caretPositionFromPoint) {
|
|
28908
|
-
const position = document.caretPositionFromPoint(x2, y2);
|
|
28909
|
-
if (position) {
|
|
28910
|
-
range = document.createRange();
|
|
28911
|
-
range.setStart(position.offsetNode, position.offset);
|
|
28912
|
-
}
|
|
28913
|
-
}
|
|
28914
|
-
if (!range)
|
|
28915
|
-
return null;
|
|
28916
|
-
const textNode = range.startContainer;
|
|
28917
|
-
if (textNode.nodeType !== Node.TEXT_NODE)
|
|
28918
|
-
return null;
|
|
28919
|
-
const text = textNode.textContent || "";
|
|
28920
|
-
let start = range.startOffset;
|
|
28921
|
-
let end = range.startOffset;
|
|
28922
|
-
while (start > 0 && /\w/.test(text[start - 1])) {
|
|
28923
|
-
start--;
|
|
28924
|
-
}
|
|
28925
|
-
while (end < text.length && /\w/.test(text[end])) {
|
|
28926
|
-
end++;
|
|
28927
|
-
}
|
|
28928
|
-
const word = text.substring(start, end).trim();
|
|
28929
|
-
return word || null;
|
|
28930
|
-
} catch (error) {
|
|
28931
|
-
console.error("Error getting word at point:", error);
|
|
28932
|
-
return null;
|
|
28933
|
-
}
|
|
28934
|
-
}, []);
|
|
28935
|
-
useEffect$1(() => {
|
|
28936
|
-
if (errors.length === 0)
|
|
28937
|
-
return;
|
|
28938
|
-
let hoverTimeout;
|
|
28939
|
-
const handleMouseMove = (e) => {
|
|
28940
|
-
clearTimeout(hoverTimeout);
|
|
28941
|
-
hoverTimeout = window.setTimeout(() => {
|
|
28942
|
-
const wordAtCursor = getWordAtPoint(e.clientX, e.clientY);
|
|
28943
|
-
if (wordAtCursor) {
|
|
28944
|
-
const matchedError = errors.find(
|
|
28945
|
-
(err) => wordAtCursor.toLowerCase() === err.original.toLowerCase()
|
|
28946
|
-
);
|
|
28947
|
-
if (matchedError) {
|
|
28948
|
-
setTooltip({
|
|
28949
|
-
error: matchedError,
|
|
28950
|
-
x: e.clientX,
|
|
28951
|
-
y: e.clientY
|
|
28952
|
-
});
|
|
28953
|
-
}
|
|
28954
|
-
}
|
|
28955
|
-
}, 50);
|
|
28956
|
-
};
|
|
28957
|
-
const handleClick = () => {
|
|
28958
|
-
setTooltip(null);
|
|
28959
|
-
};
|
|
28960
|
-
document.addEventListener("mousemove", handleMouseMove);
|
|
28961
|
-
document.addEventListener("click", handleClick);
|
|
28962
|
-
return () => {
|
|
28963
|
-
clearTimeout(hoverTimeout);
|
|
28964
|
-
document.removeEventListener("mousemove", handleMouseMove);
|
|
28965
|
-
document.removeEventListener("click", handleClick);
|
|
28966
|
-
};
|
|
28967
|
-
}, [errors, getWordAtPoint]);
|
|
28968
|
-
const applyCorrection = useCallback(
|
|
28969
|
-
(suggestion, original, errorType) => {
|
|
28970
|
-
editor.update(() => {
|
|
28971
|
-
const root2 = $getRoot();
|
|
28972
|
-
const currentText = root2.getTextContent();
|
|
28973
|
-
const isSpellingError = errorType === "spelling";
|
|
28974
|
-
let newText = currentText;
|
|
28975
|
-
if (isSpellingError) {
|
|
28976
|
-
const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28977
|
-
const regex = new RegExp(`\\b${escapedOriginal}\\b`, "gi");
|
|
28978
|
-
newText = currentText.replace(regex, suggestion);
|
|
28979
|
-
} else {
|
|
28980
|
-
const escapedOriginal = original.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
28981
|
-
const regex = new RegExp(escapedOriginal, "gi");
|
|
28982
|
-
if (currentText.toLowerCase().includes(original.toLowerCase())) {
|
|
28983
|
-
newText = currentText.replace(regex, suggestion);
|
|
28984
|
-
} else {
|
|
28985
|
-
newText = suggestion;
|
|
28986
|
-
}
|
|
28987
|
-
}
|
|
28988
|
-
root2.clear();
|
|
28989
|
-
const paragraph = $createParagraphNode();
|
|
28990
|
-
const textNode = $createTextNode(newText);
|
|
28991
|
-
paragraph.append(textNode);
|
|
28992
|
-
root2.append(paragraph);
|
|
28993
|
-
});
|
|
28994
|
-
setTooltip(null);
|
|
28995
|
-
setTimeout(() => {
|
|
28996
|
-
lastCheckedText.current = "";
|
|
28997
|
-
checkGrammar();
|
|
28998
|
-
}, 100);
|
|
28999
|
-
},
|
|
29000
|
-
[editor, checkGrammar]
|
|
29001
|
-
);
|
|
29002
|
-
const showErrorTooltip = (error, event) => {
|
|
29003
|
-
setTooltip({
|
|
29004
|
-
error,
|
|
29005
|
-
x: event.clientX,
|
|
29006
|
-
y: event.clientY
|
|
29007
|
-
});
|
|
29008
|
-
};
|
|
29009
|
-
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
29010
|
-
errors.length > 0 && !userDismissed && /* @__PURE__ */ jsx("div", { className: "grammar-error-panel", children: /* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-bg-amber-50 cteditor-border cteditor-border-amber-200 cteditor-rounded-lg cteditor-px-3 cteditor-py-2 cteditor-shadow-sm", children: [
|
|
29011
|
-
/* @__PURE__ */ jsx(AlertCircle, { className: "cteditor-h-4 cteditor-w-4 cteditor-text-amber-600 cteditor-flex-shrink-0" }),
|
|
29012
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-flex-1 cteditor-overflow-x-auto cteditor-max-w-2xl", children: [
|
|
29013
|
-
/* @__PURE__ */ jsxs("span", { className: "cteditor-text-xs cteditor-font-semibold cteditor-text-amber-800 cteditor-whitespace-nowrap", children: [
|
|
29014
|
-
errors.length,
|
|
29015
|
-
" ",
|
|
29016
|
-
errors.length === 1 ? "issue" : "issues",
|
|
29017
|
-
":"
|
|
29018
|
-
] }),
|
|
29019
|
-
/* @__PURE__ */ jsx("div", { className: "cteditor-flex cteditor-gap-2 cteditor-items-center", children: errors.map((error, idx) => /* @__PURE__ */ jsxs(
|
|
29020
|
-
"div",
|
|
29021
|
-
{
|
|
29022
|
-
className: "cteditor-flex cteditor-items-center cteditor-gap-1.5 cteditor-bg-white cteditor-border cteditor-border-gray-200 cteditor-rounded cteditor-px-2 cteditor-py-1 cteditor-whitespace-nowrap cteditor-cursor-pointer hover:cteditor-bg-gray-50 cteditor-transition-colors",
|
|
29023
|
-
onClick: (e) => showErrorTooltip(error, e),
|
|
29024
|
-
children: [
|
|
29025
|
-
/* @__PURE__ */ jsx("span", { className: "cteditor-text-xs cteditor-line-through cteditor-text-red-600 cteditor-max-w-24 cteditor-truncate", title: error.original, children: error.original }),
|
|
29026
|
-
/* @__PURE__ */ jsx("span", { className: "cteditor-text-xs cteditor-text-gray-400", children: "→" }),
|
|
29027
|
-
/* @__PURE__ */ jsx(
|
|
29028
|
-
"button",
|
|
29029
|
-
{
|
|
29030
|
-
onClick: (e) => {
|
|
29031
|
-
e.stopPropagation();
|
|
29032
|
-
applyCorrection(error.suggestions[0], error.original, error.type);
|
|
29033
|
-
},
|
|
29034
|
-
className: "cteditor-text-xs cteditor-text-green-600 hover:cteditor-text-green-700 cteditor-font-medium cteditor-max-w-24 cteditor-truncate",
|
|
29035
|
-
title: error.suggestions[0],
|
|
29036
|
-
children: error.suggestions[0]
|
|
29037
|
-
}
|
|
29038
|
-
)
|
|
29039
|
-
]
|
|
29040
|
-
},
|
|
29041
|
-
idx
|
|
29042
|
-
)) })
|
|
29043
|
-
] }),
|
|
29044
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-1 cteditor-flex-shrink-0", children: [
|
|
29045
|
-
/* @__PURE__ */ jsx(
|
|
29046
|
-
Button,
|
|
29047
|
-
{
|
|
29048
|
-
variant: "link",
|
|
29049
|
-
size: "sm",
|
|
29050
|
-
onClick: () => {
|
|
29051
|
-
setUserDismissed(true);
|
|
29052
|
-
setErrors([]);
|
|
29053
|
-
updateToolbarState("isGrammarCheckEnabled", false);
|
|
29054
|
-
},
|
|
29055
|
-
className: "cteditor-h-7 cteditor-px-2 cteditor-text-xs !cteditor-text-amber-700 ",
|
|
29056
|
-
title: "Disable Grammar Check",
|
|
29057
|
-
children: "Disable"
|
|
29058
|
-
}
|
|
29059
|
-
),
|
|
29060
|
-
/* @__PURE__ */ jsx(
|
|
29061
|
-
"button",
|
|
29062
|
-
{
|
|
29063
|
-
onClick: () => setUserDismissed(true),
|
|
29064
|
-
className: "cteditor-p-1 hover:cteditor-bg-amber-100 cteditor-rounded cteditor-transition-colors",
|
|
29065
|
-
title: "Dismiss grammar suggestions",
|
|
29066
|
-
children: /* @__PURE__ */ jsx(X$1, { className: "cteditor-h-3.5 cteditor-w-3.5 cteditor-text-amber-600" })
|
|
29067
|
-
}
|
|
29068
|
-
)
|
|
29069
|
-
] })
|
|
29070
|
-
] }) }),
|
|
29071
|
-
tooltip && createPortal(
|
|
29072
|
-
/* @__PURE__ */ jsx(
|
|
29073
|
-
"div",
|
|
29074
|
-
{
|
|
29075
|
-
className: "grammar-tooltip ",
|
|
29076
|
-
style: {
|
|
29077
|
-
position: "fixed",
|
|
29078
|
-
left: tooltip.x,
|
|
29079
|
-
top: tooltip.y + 20,
|
|
29080
|
-
zIndex: 1e4
|
|
29081
|
-
},
|
|
29082
|
-
onMouseEnter: () => {
|
|
29083
|
-
},
|
|
29084
|
-
onMouseLeave: () => {
|
|
29085
|
-
setTooltip(null);
|
|
29086
|
-
},
|
|
29087
|
-
children: /* @__PURE__ */ jsx(Card, { className: "cteditor-w-72 cteditor-shadow-xl cteditor-border-2 cteditor-bg-background cteditor-rounded-xl", children: /* @__PURE__ */ jsxs(CardContent, { className: "cteditor-p-3", children: [
|
|
29088
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-flex cteditor-items-center cteditor-gap-2 cteditor-mb-3", children: [
|
|
29089
|
-
tooltip.error.type === "spelling" ? /* @__PURE__ */ jsx(AlertCircle, { className: "cteditor-h-4 cteditor-w-4 cteditor-text-red-500" }) : /* @__PURE__ */ jsx(CheckCircle, { className: "cteditor-h-4 cteditor-w-4 cteditor-text-blue-500" }),
|
|
29090
|
-
/* @__PURE__ */ jsx(
|
|
29091
|
-
Badge,
|
|
29092
|
-
{
|
|
29093
|
-
variant: tooltip.error.type === "spelling" ? "destructive" : "default",
|
|
29094
|
-
className: "cteditor-text-xs",
|
|
29095
|
-
children: tooltip.error.type === "spelling" ? "Spelling Error" : "Grammar Issue"
|
|
29096
|
-
}
|
|
29097
|
-
)
|
|
29098
|
-
] }),
|
|
29099
|
-
tooltip.error.issue && /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-muted-foreground cteditor-mb-2 cteditor-italic", children: tooltip.error.issue }),
|
|
29100
|
-
/* @__PURE__ */ jsxs("div", { className: "cteditor-mb-2", children: [
|
|
29101
|
-
/* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-font-semibold cteditor-text-muted-foreground", children: "Original:" }),
|
|
29102
|
-
/* @__PURE__ */ jsx("p", { className: "cteditor-text-sm cteditor-line-through cteditor-text-red-600", children: tooltip.error.original })
|
|
29103
|
-
] }),
|
|
29104
|
-
tooltip.error.suggestions.length > 0 && /* @__PURE__ */ jsxs("div", { children: [
|
|
29105
|
-
/* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-font-semibold cteditor-text-muted-foreground cteditor-mb-1", children: "Suggestions:" }),
|
|
29106
|
-
/* @__PURE__ */ jsx("div", { className: "cteditor-space-y-1", children: tooltip.error.suggestions.map((suggestion, idx) => /* @__PURE__ */ jsxs(
|
|
29107
|
-
"button",
|
|
29108
|
-
{
|
|
29109
|
-
onClick: () => applyCorrection(suggestion, tooltip.error.original, tooltip.error.type),
|
|
29110
|
-
className: "cteditor-w-full cteditor-text-left cteditor-p-2 cteditor-text-sm cteditor-rounded-md cteditor-bg-accent/50 hover:cteditor-bg-accent cteditor-transition-colors cteditor-border cteditor-border-transparent hover:cteditor-border-primary",
|
|
29111
|
-
children: [
|
|
29112
|
-
"✓ ",
|
|
29113
|
-
suggestion
|
|
29114
|
-
]
|
|
29115
|
-
},
|
|
29116
|
-
idx
|
|
29117
|
-
)) })
|
|
29118
|
-
] }),
|
|
29119
|
-
tooltip.error.suggestions.length === 0 && /* @__PURE__ */ jsx("p", { className: "cteditor-text-xs cteditor-text-muted-foreground cteditor-italic", children: "No suggestions available" })
|
|
29120
|
-
] }) })
|
|
29121
|
-
}
|
|
29122
|
-
),
|
|
29123
|
-
document.body
|
|
29124
|
-
)
|
|
29125
|
-
] });
|
|
29126
|
-
}
|
|
29127
29708
|
const useStyles = () => ({
|
|
29128
29709
|
// container: "cteditor-relative cteditor-w-full cteditor-bg-white cteditor-text-black cteditor-font-normal cteditor-text-left cteditor-border cteditor-border-red-500",
|
|
29129
29710
|
contentEditable: cn$1(
|
|
29130
|
-
"cteditor-relative cteditor-min-h-[150px] !cteditor-h-auto cteditor-resize-none cteditor-outline-0
|
|
29131
|
-
|
|
29711
|
+
"cteditor-relative cteditor-min-h-[150px] !cteditor-h-auto cteditor-resize-none cteditor-outline-0",
|
|
29712
|
+
// Ensure strong contrast in both themes
|
|
29713
|
+
"cteditor-text-black dark:cteditor-text-white cteditor-bg-white dark:cteditor-bg-[#0b0b0b]",
|
|
29714
|
+
// Caret and spacing
|
|
29715
|
+
"cteditor-caret-[#3b82f6] cteditor-p-0 cteditor-transition-all cteditor-duration-200",
|
|
29132
29716
|
"cteditor-w-full ",
|
|
29133
29717
|
"[&>hr]:cteditor-border-none [&>hr]:cteditor-h-[2px]"
|
|
29134
29718
|
),
|
|
@@ -29214,12 +29798,12 @@ const ToolbarWithEditor = (props) => {
|
|
|
29214
29798
|
}
|
|
29215
29799
|
);
|
|
29216
29800
|
};
|
|
29217
|
-
const
|
|
29801
|
+
const CombinedPluginWrapper = () => {
|
|
29218
29802
|
const { toolbarState } = useToolbarState();
|
|
29219
|
-
if (!toolbarState.isAutocompleteEnabled) {
|
|
29803
|
+
if (!toolbarState.isAutocompleteEnabled && !toolbarState.isGrammarCheckEnabled) {
|
|
29220
29804
|
return null;
|
|
29221
29805
|
}
|
|
29222
|
-
return /* @__PURE__ */ jsx(
|
|
29806
|
+
return /* @__PURE__ */ jsx(CombinedAutocompleteGrammarPlugin, { minMatchLength: 2, maxSuggestions: 10, enableAI: true });
|
|
29223
29807
|
};
|
|
29224
29808
|
const OnChangeWrapper = ({ onChange }) => {
|
|
29225
29809
|
const [editor] = useLexicalComposerContext();
|
|
@@ -29346,14 +29930,15 @@ const ConfigurableEditor = ({
|
|
|
29346
29930
|
/* @__PURE__ */ jsx(HtmlSyncPlugin, {}),
|
|
29347
29931
|
/* @__PURE__ */ jsx(CodeHighlightPlugin, {}),
|
|
29348
29932
|
/* @__PURE__ */ jsx(SlashCommandPlugin, {}),
|
|
29349
|
-
/* @__PURE__ */ jsx(
|
|
29350
|
-
/* @__PURE__ */ jsx(GrammarCheckPlugin, {}),
|
|
29933
|
+
/* @__PURE__ */ jsx(CombinedPluginWrapper, {}),
|
|
29351
29934
|
/* @__PURE__ */ jsx(OnChangeWrapper, { onChange }),
|
|
29352
29935
|
/* @__PURE__ */ jsx(InitialContentPlugin, { initialContent }),
|
|
29353
29936
|
/* @__PURE__ */ jsx(HistoryPlugin, {}),
|
|
29354
29937
|
/* @__PURE__ */ jsx(LocalStoragePlugin$1, { namespace: initialConfig.namespace }),
|
|
29355
29938
|
/* @__PURE__ */ jsx(ListPlugin, {}),
|
|
29356
29939
|
/* @__PURE__ */ jsx(LinkPlugin, { hasLinkAttributes: false }),
|
|
29940
|
+
/* @__PURE__ */ jsx(DragDropPaste, {}),
|
|
29941
|
+
/* @__PURE__ */ jsx(RichTextPastePlugin, {}),
|
|
29357
29942
|
/* @__PURE__ */ jsx(FilePlugin, {}),
|
|
29358
29943
|
/* @__PURE__ */ jsx(HorizontalRulePlugin, {}),
|
|
29359
29944
|
/* @__PURE__ */ jsx(CustomHorizontalRulePlugin, {}),
|
|
@@ -29415,7 +30000,7 @@ const ScopedEditorWrapper = ({
|
|
|
29415
30000
|
className = "",
|
|
29416
30001
|
darkMode = false
|
|
29417
30002
|
}) => {
|
|
29418
|
-
return /* @__PURE__ */ jsx("div", { id: "ct-editor-f47ac10b", children: /* @__PURE__ */ jsx("div", { className: "cteditor-p-2 ", children }) });
|
|
30003
|
+
return /* @__PURE__ */ jsx("div", { id: "ct-editor-f47ac10b", className: "cteditor-max-w-full cteditor-overflow-hidden", children: /* @__PURE__ */ jsx("div", { className: "cteditor-p-2 cteditor-w-full", children }) });
|
|
29419
30004
|
};
|
|
29420
30005
|
const MessageContainer = styled.div`
|
|
29421
30006
|
display: flex;
|
|
@@ -29539,4 +30124,4 @@ export {
|
|
|
29539
30124
|
useHtmlView as u,
|
|
29540
30125
|
verifyApiKey as v
|
|
29541
30126
|
};
|
|
29542
|
-
//# sourceMappingURL=index-
|
|
30127
|
+
//# sourceMappingURL=index-8d147c36.js.map
|