@lobehub/editor 4.10.2 → 4.10.6
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.
|
@@ -73,10 +73,12 @@ const ReactEditor = ({ editor: editorProp, children, config, onInit }) => {
|
|
|
73
73
|
const composerContext = useMemo(() => {
|
|
74
74
|
return [editorProp || Editor.createEditor(), createLexicalComposerContext(null, null)];
|
|
75
75
|
}, [editorProp]);
|
|
76
|
+
const onInitRef = useRef(onInit);
|
|
77
|
+
onInitRef.current = onInit;
|
|
76
78
|
useEffect(() => {
|
|
77
79
|
const editor = composerContext[0];
|
|
78
|
-
|
|
79
|
-
}, [composerContext
|
|
80
|
+
onInitRef.current?.(editor);
|
|
81
|
+
}, [composerContext]);
|
|
80
82
|
return /* @__PURE__ */ jsxs(LexicalComposerContext, {
|
|
81
83
|
value: composerContext,
|
|
82
84
|
children: [/* @__PURE__ */ jsx(ConfigInjector, { config }), children]
|
package/es/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { $ as DOM_TEXT_TYPE, A as $createCodeMirrorNode, At as createDebugLogger, B as Editor, C as $createCodeNode$1, Ct as CONTROL_OR_META, Dt as KeyEnum, E as CodeNode$1, Et as HotkeyScopeEnum, F as $isCursorNode, Ft as init_debug, G as kernel_exports, Gt as INodeHelper, H as DataSource, I as CardLikeElementNode, It as prodSafeLogger, J as $getNearestNodeFromDOMNode, K as $closest, Kt as init_helper, M as CodeMirrorNode, Mt as debugLoggers, N as $createCursorNode, Nt as debug_exports, Ot as init_hotkey, P as $isCardLikeElementNode, Pt as devConsole, Q as DOM_ELEMENT_TYPE, R as cursorNodeSerialized, S as formatUrl, St as init_registerHotkey, Tt as HotkeyEnum, U as Kernel, V as resetRandomKey, W as init_kernel, X as DOM_DOCUMENT_FRAGMENT_TYPE, Y as $getNodeFromDOMNode, Yt as __toCommonJS, Z as DOM_DOCUMENT_TYPE, _ as AutoLinkNode, _t as unregisterEditorKernel, a as $createMathBlockNode, at as generateEditorId, b as LinkNode, bt as HOVER_COMMAND, c as MathBlockNode, ct as getNodeKeyFromDOMNode, dt as isDOMNode, et as EDITOR_THEME_KEY, f as LinkHighlightNode, ft as isDocumentFragment, g as $toggleLink, gt as registerEditorKernel, h as $isLinkNode, ht as reconcileDecorator, it as genServiceId, j as $isCodeMirrorNode, jt as debugLogger, kt as browserDebug, l as MathInlineNode, lt as getParentElement, m as $createLinkNode, mt as noop, nt as compareNodeOrder, o as $createMathInlineNode, ot as getKernelFromEditor, pt as moment, q as $closestNodeType, rt as createEmptyEditorState, s as $isMathNode, st as getKernelFromEditorConfig, tt as assert, u as $createLinkHighlightNode, ut as init_utils, v as HOVER_LINK_COMMAND, vt as KernelPlugin, wt as init_sys, x as TOGGLE_LINK_COMMAND, xt as getHotkeyById, y as HOVER_OUT_LINK_COMMAND, yt as init_plugin } from "./style-CLtp6okE.js";
|
|
2
|
-
import { A as detectLanguage, B as INodePlugin, C as ReactPlainText, D as useTranslation, E as ReactMarkdownPlugin, F as GET_MARKDOWN_SELECTION_COMMAND, G as idToChar, H as $cloneNode, I as INSERT_MARKDOWN_COMMAND, J as useLexicalEditor, K as INSERT_HEADING_COMMAND, L as isPunctuationChar, M as MARKDOWN_READER_LEVEL_HIGH, N as MARKDOWN_READER_LEVEL_NORMAL, O as MarkdownPlugin, P as MARKDOWN_WRITER_LEVEL_MAX, R as ILitexmlService, S as registerCodeInlineCommand, T as CommonPlugin, U as $parseSerializedNodeImpl, V as INodeService, W as charToId, X as useLexicalComposerContext, Y as ReactEditor, Z as LexicalErrorBoundary, _ as extractUrlFromText, a as ReactMentionPlugin, c as INSERT_LINK_HIGHLIGHT_COMMAND, d as bundledLanguagesInfo, f as CodeblockPlugin, g as registerCheckList, h as INSERT_CHECK_LIST_COMMAND, i as SlashPlugin, j as IMarkdownShortCutService, k as detectCodeLanguage, l as registerLinkHighlightCommand, m as getCodeLanguageByInput, n as ReactSlashOption, o as MentionPlugin, p as UPDATE_CODEBLOCK_LANG, q as INSERT_QUOTE_COMMAND, r as SlashMenu, s as INSERT_MENTION_COMMAND, t as ReactSlashPlugin, u as useLexicalNodeSelection, v as getSelectedNode, w as ReactEditorContent, x as INSERT_CODEINLINE_COMMAND, y as sanitizeUrl, z as LitexmlService } from "./ReactSlashPlugin-
|
|
2
|
+
import { A as detectLanguage, B as INodePlugin, C as ReactPlainText, D as useTranslation, E as ReactMarkdownPlugin, F as GET_MARKDOWN_SELECTION_COMMAND, G as idToChar, H as $cloneNode, I as INSERT_MARKDOWN_COMMAND, J as useLexicalEditor, K as INSERT_HEADING_COMMAND, L as isPunctuationChar, M as MARKDOWN_READER_LEVEL_HIGH, N as MARKDOWN_READER_LEVEL_NORMAL, O as MarkdownPlugin, P as MARKDOWN_WRITER_LEVEL_MAX, R as ILitexmlService, S as registerCodeInlineCommand, T as CommonPlugin, U as $parseSerializedNodeImpl, V as INodeService, W as charToId, X as useLexicalComposerContext, Y as ReactEditor, Z as LexicalErrorBoundary, _ as extractUrlFromText, a as ReactMentionPlugin, c as INSERT_LINK_HIGHLIGHT_COMMAND, d as bundledLanguagesInfo, f as CodeblockPlugin, g as registerCheckList, h as INSERT_CHECK_LIST_COMMAND, i as SlashPlugin, j as IMarkdownShortCutService, k as detectCodeLanguage, l as registerLinkHighlightCommand, m as getCodeLanguageByInput, n as ReactSlashOption, o as MentionPlugin, p as UPDATE_CODEBLOCK_LANG, q as INSERT_QUOTE_COMMAND, r as SlashMenu, s as INSERT_MENTION_COMMAND, t as ReactSlashPlugin, u as useLexicalNodeSelection, v as getSelectedNode, w as ReactEditorContent, x as INSERT_CODEINLINE_COMMAND, y as sanitizeUrl, z as LitexmlService } from "./ReactSlashPlugin-DftZMdq9.js";
|
|
3
3
|
import { S as DiffNode, _ as PlaceholderNode, a as styles$16, b as HorizontalRuleNode, c as ImageNode, d as BlockImageNode, f as styles$15, g as PlaceholderBlockNode, h as FileNode, i as imageBroken, l as $createBlockImageNode, m as $isFileNode, n as styles$18, o as $createImageNode, p as $createFileNode, r as styles$17, s as $isImageNode, t as styles$19, u as $isBlockImageNode, v as $createHorizontalRuleNode, x as $createDiffNode, y as $isHorizontalRuleNode } from "./style-D-dIPHv5.js";
|
|
4
4
|
import { $computeTableMapSkipCellCheck, $createTableNodeWithDimensions, $createTableSelection, $deleteTableColumnAtSelection, $deleteTableRowAtSelection, $findTableNode, $getElementForTableNode, $getNodeTriplet, $getTableAndElementByKey, $getTableCellNodeFromLexicalNode, $getTableColumnIndexFromTableCellNode, $getTableNodeFromLexicalNodeOrThrow, $getTableRowIndexFromTableCellNode, $insertTableColumnAtSelection, $insertTableRowAtSelection, $isTableCellNode, $isTableNode, $isTableRowNode, $isTableSelection, $mergeCells, $unmergeCell, TableCellHeaderStates, TableCellNode, TableNode, TableNode as TableNode$1, TableRowNode, getDOMCellFromTarget, getTableElement, getTableObserverFromTableElement, registerTableCellUnmergeTransform, registerTablePlugin, registerTableSelectionObserver, setScrollableTablesActive } from "@lexical/table";
|
|
5
5
|
import { debounce } from "es-toolkit/compat";
|
|
6
6
|
import EventEmitter from "eventemitter3";
|
|
7
|
-
import { $createNodeSelection, $createParagraphNode, $createRangeSelection, $createTextNode, $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode$1, $getNodeByKey, $getPreviousSelection, $getRoot, $getSelection, $insertNodes, $isBlockElementNode, $isDecoratorNode, $isElementNode, $isNodeSelection, $isRangeSelection, $isRootNode, $isRootOrShadowRoot, $isTextNode, $nodesOfType, $normalizeSelection__EXPERIMENTAL, $setSelection, CLICK_COMMAND, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_LOW, COMMAND_PRIORITY_NORMAL, DROP_COMMAND, HISTORY_MERGE_TAG, INDENT_CONTENT_COMMAND, INSERT_TAB_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_UP_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DOWN_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, PASTE_COMMAND, ParagraphNode, SELECTION_CHANGE_COMMAND, SKIP_SCROLL_INTO_VIEW_TAG, TabNode, TextNode, createCommand, getDOMSelection, getDOMSelectionFromTarget, isHTMLElement, isModifierMatch } from "lexical";
|
|
7
|
+
import { $createNodeSelection, $createParagraphNode, $createRangeSelection, $createTextNode, $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode$1, $getNodeByKey, $getPreviousSelection, $getRoot, $getSelection, $insertNodes, $isBlockElementNode, $isDecoratorNode, $isElementNode, $isNodeSelection, $isRangeSelection, $isRootNode, $isRootOrShadowRoot, $isTextNode, $nodesOfType, $normalizeSelection__EXPERIMENTAL, $setSelection, CLICK_COMMAND, COMMAND_PRIORITY_CRITICAL, COMMAND_PRIORITY_EDITOR, COMMAND_PRIORITY_HIGH, COMMAND_PRIORITY_LOW, COMMAND_PRIORITY_NORMAL, DROP_COMMAND, HISTORY_MERGE_TAG, INDENT_CONTENT_COMMAND, INSERT_TAB_COMMAND, KEY_ARROW_DOWN_COMMAND, KEY_ARROW_LEFT_COMMAND, KEY_ARROW_RIGHT_COMMAND, KEY_ARROW_UP_COMMAND, KEY_BACKSPACE_COMMAND, KEY_DOWN_COMMAND, KEY_ESCAPE_COMMAND, KEY_TAB_COMMAND, OUTDENT_CONTENT_COMMAND, PASTE_COMMAND, ParagraphNode, SELECTION_CHANGE_COMMAND, SKIP_SCROLL_INTO_VIEW_TAG, TabNode, TextNode, createCommand, getDOMSelection, getDOMSelectionFromTarget, isHTMLElement, isModifierMatch } from "lexical";
|
|
8
8
|
import { DRAG_DROP_PASTE } from "@lexical/rich-text";
|
|
9
9
|
import { $filter, $findMatchingParent, $getNearestBlockElementAncestorOrThrow, $getNearestNodeOfType, $insertNodeToNearestRoot, $wrapNodeInElement, addClassNamesToElement, calculateZoomLevel, mergeRegister, removeClassNamesFromElement } from "@lexical/utils";
|
|
10
10
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -2271,12 +2271,9 @@ function createHeadlessEditor(options) {
|
|
|
2271
2271
|
}
|
|
2272
2272
|
//#endregion
|
|
2273
2273
|
//#region src/plugins/auto-complete/plugin/index.ts
|
|
2274
|
-
init_helper();
|
|
2275
2274
|
init_plugin();
|
|
2276
2275
|
init_debug();
|
|
2277
2276
|
const AUTO_COMPLETE_GUARD_LIMIT = 5e4;
|
|
2278
|
-
const CLEAR_PLACEHOLDER_BURST_LIMIT = 20;
|
|
2279
|
-
const CLEAR_PLACEHOLDER_BURST_WINDOW_MS = 1e3;
|
|
2280
2277
|
const AutoCompletePlugin = class extends KernelPlugin {
|
|
2281
2278
|
static {
|
|
2282
2279
|
this.pluginName = "AutoCompletePlugin";
|
|
@@ -2289,11 +2286,11 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2289
2286
|
this.lastCursorPosition = null;
|
|
2290
2287
|
this.cursorStableTimer = null;
|
|
2291
2288
|
this.abortController = null;
|
|
2292
|
-
this.placeholderNodes = [];
|
|
2293
2289
|
this.currentSuggestion = null;
|
|
2290
|
+
this.placeholderAnchorPosition = null;
|
|
2291
|
+
this.placeholderSelectionSnapshot = null;
|
|
2294
2292
|
this.markdownService = null;
|
|
2295
2293
|
this.skipNextTextContentListener = false;
|
|
2296
|
-
this.clearPlaceholderCallTimestamps = [];
|
|
2297
2294
|
this.delay = config?.delay ?? 1e3;
|
|
2298
2295
|
kernel.registerNodes([PlaceholderNode, PlaceholderBlockNode]);
|
|
2299
2296
|
if (config?.theme) kernel.registerThemes(config?.theme);
|
|
@@ -2308,13 +2305,13 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2308
2305
|
editorState.read(() => {
|
|
2309
2306
|
if (editor.isComposing()) {
|
|
2310
2307
|
this.clearTimer();
|
|
2311
|
-
this.clearPlaceholderNodes(editor);
|
|
2308
|
+
if (this.currentSuggestion) this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2312
2309
|
return;
|
|
2313
2310
|
}
|
|
2314
2311
|
const selection = $getSelection();
|
|
2315
2312
|
if (!$isRangeSelection(selection) || !selection.isCollapsed()) {
|
|
2316
2313
|
this.clearTimer();
|
|
2317
|
-
this.clearPlaceholderNodes(editor);
|
|
2314
|
+
if (this.currentSuggestion) this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2318
2315
|
return;
|
|
2319
2316
|
}
|
|
2320
2317
|
const currentPosition = {
|
|
@@ -2324,7 +2321,7 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2324
2321
|
};
|
|
2325
2322
|
if (this.hasPositionChanged(currentPosition)) {
|
|
2326
2323
|
this.clearTimer();
|
|
2327
|
-
this.clearPlaceholderNodes(editor);
|
|
2324
|
+
if (this.currentSuggestion) this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2328
2325
|
this.abortController = new AbortController();
|
|
2329
2326
|
this.cursorStableTimer = window.setTimeout(() => {
|
|
2330
2327
|
this.handleCursorStable(editor, currentPosition);
|
|
@@ -2340,11 +2337,24 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2340
2337
|
}
|
|
2341
2338
|
return false;
|
|
2342
2339
|
}, COMMAND_PRIORITY_HIGH));
|
|
2340
|
+
this.register(editor.registerCommand(KEY_ARROW_LEFT_COMMAND, () => {
|
|
2341
|
+
if (this.currentSuggestion) {
|
|
2342
|
+
this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2343
|
+
return false;
|
|
2344
|
+
}
|
|
2345
|
+
return false;
|
|
2346
|
+
}, COMMAND_PRIORITY_CRITICAL));
|
|
2347
|
+
this.register(editor.registerCommand(KEY_ARROW_RIGHT_COMMAND, () => {
|
|
2348
|
+
if (this.currentSuggestion) {
|
|
2349
|
+
this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2350
|
+
return false;
|
|
2351
|
+
}
|
|
2352
|
+
return false;
|
|
2353
|
+
}, COMMAND_PRIORITY_CRITICAL));
|
|
2343
2354
|
this.register(editor.registerCommand(KEY_ESCAPE_COMMAND, (event) => {
|
|
2344
2355
|
if (this.currentSuggestion) {
|
|
2345
2356
|
event?.preventDefault();
|
|
2346
2357
|
this.clearPlaceholderNodes(editor);
|
|
2347
|
-
this.currentSuggestion = null;
|
|
2348
2358
|
return true;
|
|
2349
2359
|
}
|
|
2350
2360
|
return false;
|
|
@@ -2354,7 +2364,7 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2354
2364
|
this.skipNextTextContentListener = false;
|
|
2355
2365
|
return;
|
|
2356
2366
|
}
|
|
2357
|
-
if (this.currentSuggestion) this.clearPlaceholderNodes(editor);
|
|
2367
|
+
if (this.currentSuggestion) this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2358
2368
|
}));
|
|
2359
2369
|
}
|
|
2360
2370
|
hasPositionChanged(currentPosition) {
|
|
@@ -2372,7 +2382,7 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2372
2382
|
editor.getEditorState().read(() => {
|
|
2373
2383
|
if (editor.isComposing()) {
|
|
2374
2384
|
this.clearTimer();
|
|
2375
|
-
this.clearPlaceholderNodes(editor);
|
|
2385
|
+
if (this.currentSuggestion) this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2376
2386
|
return;
|
|
2377
2387
|
}
|
|
2378
2388
|
if (!this.abortController || this.abortController.signal.aborted) return;
|
|
@@ -2387,9 +2397,8 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2387
2397
|
if (this.lastCursorPosition && this.isSamePosition(position, this.lastCursorPosition)) return;
|
|
2388
2398
|
this.lastCursorPosition = currentPosition;
|
|
2389
2399
|
const anchorNode = selection.anchor.getNode();
|
|
2390
|
-
let selectionType = "unknown";
|
|
2391
2400
|
const textRet = this.getTextBeforeCursor(selection);
|
|
2392
|
-
selectionType = anchorNode.getType();
|
|
2401
|
+
const selectionType = anchorNode.getType();
|
|
2393
2402
|
if (this.config?.onAutoComplete) this.config.onAutoComplete({
|
|
2394
2403
|
abortSignal: this.abortController.signal,
|
|
2395
2404
|
afterText: textRet.textAfter,
|
|
@@ -2402,11 +2411,11 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2402
2411
|
currentSelection = $getSelection();
|
|
2403
2412
|
});
|
|
2404
2413
|
if (editor.isComposing()) {
|
|
2405
|
-
this.clearPlaceholderNodes(editor);
|
|
2414
|
+
this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2406
2415
|
return;
|
|
2407
2416
|
}
|
|
2408
2417
|
if (!currentSelection || !$isRangeSelection(currentSelection) || !currentSelection.isCollapsed()) {
|
|
2409
|
-
this.clearPlaceholderNodes(editor);
|
|
2418
|
+
this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2410
2419
|
return;
|
|
2411
2420
|
}
|
|
2412
2421
|
const newPosition = {
|
|
@@ -2415,11 +2424,12 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2415
2424
|
type: currentSelection.anchor.type
|
|
2416
2425
|
};
|
|
2417
2426
|
if (!this.isSamePosition(currentPosition, newPosition)) {
|
|
2418
|
-
this.clearPlaceholderNodes(editor);
|
|
2427
|
+
this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2419
2428
|
return;
|
|
2420
2429
|
}
|
|
2421
2430
|
if (result) {
|
|
2422
2431
|
this.currentSuggestion = result;
|
|
2432
|
+
this.placeholderAnchorPosition = currentPosition;
|
|
2423
2433
|
this.showPlaceholderNodes(editor, result);
|
|
2424
2434
|
this.logger.debug("🔍 Auto-complete triggered:", {
|
|
2425
2435
|
afterText: textRet.textAfter,
|
|
@@ -2428,15 +2438,11 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2428
2438
|
result,
|
|
2429
2439
|
selectionType
|
|
2430
2440
|
});
|
|
2431
|
-
} else this.clearPlaceholderNodes(editor);
|
|
2441
|
+
} else this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2432
2442
|
});
|
|
2433
2443
|
});
|
|
2434
2444
|
}
|
|
2435
2445
|
getTextBeforeCursor(selection) {
|
|
2436
|
-
const ret = {
|
|
2437
|
-
textAfter: "",
|
|
2438
|
-
textBefore: ""
|
|
2439
|
-
};
|
|
2440
2446
|
const anchorNode = selection.anchor.getNode();
|
|
2441
2447
|
const anchorOffset = selection.anchor.offset;
|
|
2442
2448
|
let paragraphNode = anchorNode;
|
|
@@ -2448,7 +2454,10 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2448
2454
|
if (!parent) break;
|
|
2449
2455
|
paragraphNode = parent;
|
|
2450
2456
|
}
|
|
2451
|
-
if (!paragraphNode) return
|
|
2457
|
+
if (!paragraphNode) return {
|
|
2458
|
+
textAfter: "",
|
|
2459
|
+
textBefore: ""
|
|
2460
|
+
};
|
|
2452
2461
|
this.logger.debug("🔍 Paragraph Node Type:", paragraphNode, anchorNode);
|
|
2453
2462
|
let founded = false;
|
|
2454
2463
|
let recursionDepth = 0;
|
|
@@ -2504,6 +2513,8 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2504
2513
|
this.logger.warn("⚠️ No valid markdown service for placeholder");
|
|
2505
2514
|
return;
|
|
2506
2515
|
}
|
|
2516
|
+
for (const node of $nodesOfType(PlaceholderNode)) node.remove();
|
|
2517
|
+
for (const node of $nodesOfType(PlaceholderBlockNode)) node.remove();
|
|
2507
2518
|
const nodes = this.markdownService.parseMarkdownToLexical(suggestion);
|
|
2508
2519
|
if (nodes.children[0]) {
|
|
2509
2520
|
const firstChild = nodes.children[0];
|
|
@@ -2519,51 +2530,32 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2519
2530
|
type: "PlaceholderBlock"
|
|
2520
2531
|
};
|
|
2521
2532
|
}
|
|
2522
|
-
const markerNode = INodeHelper.createTextNode("");
|
|
2523
|
-
nodes.children.push({
|
|
2524
|
-
children: [markerNode],
|
|
2525
|
-
name: "",
|
|
2526
|
-
type: "PlaceholderInline"
|
|
2527
|
-
});
|
|
2528
2533
|
const saveSel = selection.clone();
|
|
2534
|
+
this.placeholderSelectionSnapshot = saveSel;
|
|
2529
2535
|
this.markdownService.insertIRootNode(editor, nodes, selection);
|
|
2530
2536
|
$setSelection(saveSel);
|
|
2531
2537
|
});
|
|
2532
2538
|
}
|
|
2533
|
-
clearPlaceholderNodes(editor) {
|
|
2534
|
-
const
|
|
2535
|
-
|
|
2536
|
-
if (this.clearPlaceholderCallTimestamps.length >= CLEAR_PLACEHOLDER_BURST_LIMIT) return;
|
|
2537
|
-
this.clearPlaceholderCallTimestamps.push(now);
|
|
2538
|
-
this.skipNextTextContentListener = true;
|
|
2539
|
+
clearPlaceholderNodes(editor, options) {
|
|
2540
|
+
const shouldRestoreSelection = options?.restoreSelection ?? true;
|
|
2541
|
+
const restoreSelection = this.placeholderSelectionSnapshot;
|
|
2539
2542
|
this.currentSuggestion = null;
|
|
2540
|
-
this.
|
|
2543
|
+
this.placeholderAnchorPosition = null;
|
|
2544
|
+
this.placeholderSelectionSnapshot = null;
|
|
2545
|
+
this.clearTimer();
|
|
2546
|
+
let hasPlaceholderNodes = false;
|
|
2547
|
+
editor.getEditorState().read(() => {
|
|
2548
|
+
hasPlaceholderNodes = $nodesOfType(PlaceholderNode).length > 0 || $nodesOfType(PlaceholderBlockNode).length > 0;
|
|
2549
|
+
});
|
|
2550
|
+
if (!hasPlaceholderNodes && !(shouldRestoreSelection && restoreSelection)) {
|
|
2551
|
+
this.skipNextTextContentListener = false;
|
|
2552
|
+
return;
|
|
2553
|
+
}
|
|
2554
|
+
this.skipNextTextContentListener = true;
|
|
2541
2555
|
editor.update(() => {
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
if (iterCount > AUTO_COMPLETE_GUARD_LIMIT) throw new Error(`clearPlaceholderNodes: forEach loop > ${AUTO_COMPLETE_GUARD_LIMIT} iterations`);
|
|
2546
|
-
const selection = $getSelection();
|
|
2547
|
-
const clonedSelection = selection ? selection.clone() : null;
|
|
2548
|
-
if (node.isAttached() && ["PlaceholderBlock", "PlaceholderInline"].includes(node.getType())) {
|
|
2549
|
-
if (node.getType() === "PlaceholderInline" && node.getTextContent().includes("") && node.getPreviousSibling() === null) {
|
|
2550
|
-
const siblings = [];
|
|
2551
|
-
let sibling = node.getNextSibling();
|
|
2552
|
-
let siblingLoopCount = 0;
|
|
2553
|
-
while (sibling && siblingLoopCount < AUTO_COMPLETE_GUARD_LIMIT) {
|
|
2554
|
-
siblings.push(sibling);
|
|
2555
|
-
sibling = sibling.getNextSibling();
|
|
2556
|
-
siblingLoopCount++;
|
|
2557
|
-
}
|
|
2558
|
-
if (siblingLoopCount >= AUTO_COMPLETE_GUARD_LIMIT) throw new Error(`clearPlaceholderNodes: too many siblings (${siblingLoopCount}/${AUTO_COMPLETE_GUARD_LIMIT})`);
|
|
2559
|
-
node.getParent()?.remove();
|
|
2560
|
-
if (siblings.length > 0) $insertNodes(siblings);
|
|
2561
|
-
$setSelection(clonedSelection);
|
|
2562
|
-
return;
|
|
2563
|
-
}
|
|
2564
|
-
node.remove();
|
|
2565
|
-
}
|
|
2566
|
-
});
|
|
2556
|
+
for (const node of $nodesOfType(PlaceholderNode)) node.remove();
|
|
2557
|
+
for (const node of $nodesOfType(PlaceholderBlockNode)) node.remove();
|
|
2558
|
+
if (shouldRestoreSelection && restoreSelection) $setSelection(restoreSelection);
|
|
2567
2559
|
});
|
|
2568
2560
|
}
|
|
2569
2561
|
applySuggestion(editor) {
|
|
@@ -2572,13 +2564,11 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2572
2564
|
editor.update(() => {
|
|
2573
2565
|
const selection = $getSelection();
|
|
2574
2566
|
if (!$isRangeSelection(selection) || !selection.isCollapsed() || !this.markdownService) return;
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
});
|
|
2567
|
+
for (const node of $nodesOfType(PlaceholderNode)) node.remove();
|
|
2568
|
+
for (const node of $nodesOfType(PlaceholderBlockNode)) node.remove();
|
|
2578
2569
|
const nodes = this.markdownService.parseMarkdownToLexical(markdown);
|
|
2579
2570
|
this.markdownService.insertIRootNode(editor, nodes, selection);
|
|
2580
|
-
this.clearPlaceholderNodes(editor);
|
|
2581
|
-
this.currentSuggestion = null;
|
|
2571
|
+
this.clearPlaceholderNodes(editor, { restoreSelection: false });
|
|
2582
2572
|
});
|
|
2583
2573
|
}
|
|
2584
2574
|
isSamePosition(pos1, pos2) {
|
|
@@ -2586,7 +2576,6 @@ const AutoCompletePlugin = class extends KernelPlugin {
|
|
|
2586
2576
|
}
|
|
2587
2577
|
destroy() {
|
|
2588
2578
|
this.clearTimer();
|
|
2589
|
-
this.placeholderNodes = [];
|
|
2590
2579
|
super.destroy();
|
|
2591
2580
|
}
|
|
2592
2581
|
};
|
|
@@ -5061,6 +5050,10 @@ const ResizeHandle = ({ imageRef, isBlock, onResize, onResizeEnd, onResizeStart,
|
|
|
5061
5050
|
ResizeHandle.displayName = "ResizeHandle";
|
|
5062
5051
|
//#endregion
|
|
5063
5052
|
//#region src/plugins/image/react/components/Image.tsx
|
|
5053
|
+
function getResizedImageWidth(startWidth, deltaX, maxWidth) {
|
|
5054
|
+
const adjustedDeltaX = deltaX * 2;
|
|
5055
|
+
return Math.max(50, Math.min(startWidth + adjustedDeltaX, maxWidth));
|
|
5056
|
+
}
|
|
5064
5057
|
const Image$1 = memo(({ node, className, showScaleInfo = false, handleUpload, onPickFile }) => {
|
|
5065
5058
|
const [isSelected, setSelected] = useLexicalNodeSelection(node.getKey());
|
|
5066
5059
|
const [isHovered, setIsHovered] = useState(false);
|
|
@@ -5096,8 +5089,7 @@ const Image$1 = memo(({ node, className, showScaleInfo = false, handleUpload, on
|
|
|
5096
5089
|
if (!imageRef.current) return;
|
|
5097
5090
|
const aspectRatio = originalSizeRef.current.width / originalSizeRef.current.height;
|
|
5098
5091
|
const maxWidth = imageRef.current.parentElement?.clientWidth || window.innerWidth;
|
|
5099
|
-
const
|
|
5100
|
-
const newWidth = Math.max(50, Math.min(startWidthRef.current + adjustedDeltaX, maxWidth));
|
|
5092
|
+
const newWidth = getResizedImageWidth(startWidthRef.current, deltaX, maxWidth);
|
|
5101
5093
|
setSize({
|
|
5102
5094
|
height: newWidth / aspectRatio,
|
|
5103
5095
|
width: newWidth
|
|
@@ -5171,8 +5163,7 @@ const Image$1 = memo(({ node, className, showScaleInfo = false, handleUpload, on
|
|
|
5171
5163
|
if (!originalSizeRef.current.width || !originalSizeRef.current.height) return;
|
|
5172
5164
|
if (!imageRef.current) return;
|
|
5173
5165
|
const maxWidth = imageRef.current.parentElement?.clientWidth || window.innerWidth;
|
|
5174
|
-
const
|
|
5175
|
-
const finalWidth = Math.max(50, Math.min(startWidthRef.current + adjustedDeltaX, maxWidth));
|
|
5166
|
+
const finalWidth = getResizedImageWidth(startWidthRef.current, deltaX, maxWidth);
|
|
5176
5167
|
const editor = editorRef.current;
|
|
5177
5168
|
if (!editor) return;
|
|
5178
5169
|
editor.update(() => {
|
package/es/react.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { A as $createCodeMirrorNode, B as Editor$2, Bt as $isRootTextContentEmpty, S as formatUrl, T as $isSelectionInCodeInline, Ut as init_utils, a as $createMathBlockNode, d as $isLinkHighlightNode, h as $isLinkNode, j as $isCodeMirrorNode, mt as noop, o as $createMathInlineNode, x as TOGGLE_LINK_COMMAND } from "./style-CLtp6okE.js";
|
|
2
|
-
import { C as ReactPlainText, E as ReactMarkdownPlugin, Y as ReactEditor, _ as extractUrlFromText, a as ReactMentionPlugin, b as validateUrl, c as INSERT_LINK_HIGHLIGHT_COMMAND, h as INSERT_CHECK_LIST_COMMAND, n as ReactSlashOption, p as UPDATE_CODEBLOCK_LANG, t as ReactSlashPlugin, w as ReactEditorContent, x as INSERT_CODEINLINE_COMMAND, y as sanitizeUrl } from "./ReactSlashPlugin-
|
|
2
|
+
import { C as ReactPlainText, E as ReactMarkdownPlugin, Y as ReactEditor, _ as extractUrlFromText, a as ReactMentionPlugin, b as validateUrl, c as INSERT_LINK_HIGHLIGHT_COMMAND, h as INSERT_CHECK_LIST_COMMAND, n as ReactSlashOption, p as UPDATE_CODEBLOCK_LANG, t as ReactSlashPlugin, w as ReactEditorContent, x as INSERT_CODEINLINE_COMMAND, y as sanitizeUrl } from "./ReactSlashPlugin-DftZMdq9.js";
|
|
3
3
|
import { $createNodeSelection, $createParagraphNode, $getSelection, $isParagraphNode, $isRangeSelection, $isRootOrShadowRoot, $setSelection, CAN_REDO_COMMAND, CAN_UNDO_COMMAND, COMMAND_PRIORITY_LOW, FORMAT_TEXT_COMMAND, REDO_COMMAND, SELECTION_CHANGE_COMMAND, UNDO_COMMAND } from "lexical";
|
|
4
4
|
import { $createQuoteNode, $isHeadingNode, $isQuoteNode } from "@lexical/rich-text";
|
|
5
5
|
import { $findMatchingParent, $getNearestNodeOfType, mergeRegister } from "@lexical/utils";
|
|
@@ -1442,7 +1442,7 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
1442
1442
|
}));
|
|
1443
1443
|
//#endregion
|
|
1444
1444
|
//#region src/react/SendButton/SendButton.tsx
|
|
1445
|
-
const SendButton = ({ type = "primary", menu, className, style, loading, generating, size = 32, shape, onSend, onStop, disabled, onClick, ...rest }) => {
|
|
1445
|
+
const SendButton = ({ type = "primary", menu, className, style, loading, generating, size = 32, shape, onSend, onStop, disabled, onClick, styles: _styles, classNames: _classNames, ...rest }) => {
|
|
1446
1446
|
const cssVariables = useMemo(() => ({ "--send-button-size": `${size}px` }), [size]);
|
|
1447
1447
|
if (generating) return /* @__PURE__ */ jsx(Button, {
|
|
1448
1448
|
className: cx(styles.loadingButton, className),
|
package/package.json
CHANGED