@lobehub/editor 4.14.0 → 4.15.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/es/index.js CHANGED
@@ -1,23 +1,25 @@
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-DjwW7ClE.js";
2
- import { $ as useLexicalComposerContext, A as MarkdownPlugin, B as isPunctuationChar, C as INSERT_CODEINLINE_COMMAND, D as CommonPlugin, E as ReactEditorContent, F as MARKDOWN_READER_LEVEL_NORMAL, G as $cloneNode, H as LitexmlService, I as MARKDOWN_WRITER_LEVEL_MAX, J as idToChar, K as $parseSerializedNodeImpl, L as MarkdownWriterContext, M as detectLanguage, N as IMarkdownShortCutService, O as ReactMarkdownPlugin, P as MARKDOWN_READER_LEVEL_HIGH, Q as ReactEditor, R as GET_MARKDOWN_SELECTION_COMMAND, T as ReactPlainText, U as INodePlugin, V as ILitexmlService, W as INodeService, X as INSERT_QUOTE_COMMAND, Y as INSERT_HEADING_COMMAND, Z as useLexicalEditor, _ as INSERT_CHECK_LIST_COMMAND, a as ReactMentionPlugin, b as getSelectedNode, c as INSERT_LINK_HIGHLIGHT_COMMAND, d as bundledLanguagesInfo, et as LexicalErrorBoundary, f as CodeblockPlugin, g as getCodeLanguageByInput, h as IBlockMenuService, i as SlashPlugin, j as detectCodeLanguage, k as useTranslation, l as registerLinkHighlightCommand, m as BlockMenuService, n as ReactSlashOption, o as MentionPlugin, p as UPDATE_CODEBLOCK_LANG, q as charToId, r as SlashMenu, s as INSERT_MENTION_COMMAND, t as ReactSlashPlugin, u as useLexicalNodeSelection, v as registerCheckList, w as registerCodeInlineCommand, x as sanitizeUrl, y as extractUrlFromText, z as INSERT_MARKDOWN_COMMAND } from "./ReactSlashPlugin-DDlIT9Qd.js";
3
- import { S as DiffNode, _ as PlaceholderNode, a as styles$17, b as HorizontalRuleNode, c as ImageNode, d as BlockImageNode, f as styles$16, g as PlaceholderBlockNode, h as FileNode, i as imageBroken, l as $createBlockImageNode, m as $isFileNode, n as styles$19, o as $createImageNode, p as $createFileNode, r as styles$18, s as $isImageNode, t as styles$20, u as $isBlockImageNode, v as $createHorizontalRuleNode, x as $createDiffNode, y as $isHorizontalRuleNode } from "./style-DejqW6OX.js";
1
+ import { a as debug_exports, c as prodSafeLogger, f as __toCommonJS, i as debugLoggers, n as createDebugLogger, o as devConsole, r as debugLogger, s as init_debug, t as browserDebug } from "./debug-CIvbNHJu.js";
2
+ import { i as Toolbar, n as styles$14, r as loadCodeMirror, s as LANGUAGES, t as lobeTheme } from "./codemirror-3POv7f__.js";
3
+ import { $ as DOM_TEXT_TYPE, A as $createCodeMirrorNode, 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, G as kernel_exports, H as DataSource, I as CardLikeElementNode, J as $getNearestNodeFromDOMNode, K as $closest, Lt as INodeHelper, M as CodeMirrorNode, N as $createCursorNode, Ot as init_hotkey, P as $isCardLikeElementNode, Q as DOM_ELEMENT_TYPE, R as cursorNodeSerialized, Rt as init_helper, 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, 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, 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-DADgHVA1.js";
4
+ import { $ as useLexicalComposerContext, A as MarkdownPlugin, B as isPunctuationChar, C as INSERT_CODEINLINE_COMMAND, D as CommonPlugin, E as ReactEditorContent, F as MARKDOWN_READER_LEVEL_NORMAL, G as $cloneNode, H as LitexmlService, I as MARKDOWN_WRITER_LEVEL_MAX, J as idToChar, K as $parseSerializedNodeImpl, L as MarkdownWriterContext, M as detectLanguage, N as IMarkdownShortCutService, O as ReactMarkdownPlugin, P as MARKDOWN_READER_LEVEL_HIGH, Q as ReactEditor, R as GET_MARKDOWN_SELECTION_COMMAND, T as ReactPlainText, U as INodePlugin, V as ILitexmlService, W as INodeService, X as INSERT_QUOTE_COMMAND, Y as INSERT_HEADING_COMMAND, Z as useLexicalEditor, _ as INSERT_CHECK_LIST_COMMAND, a as ReactMentionPlugin, b as getSelectedNode, c as INSERT_LINK_HIGHLIGHT_COMMAND, d as bundledLanguagesInfo, et as LexicalErrorBoundary, f as CodeblockPlugin, g as getCodeLanguageByInput, h as IBlockMenuService, i as SlashPlugin, j as detectCodeLanguage, k as useTranslation, l as registerLinkHighlightCommand, m as BlockMenuService, n as ReactSlashOption, o as MentionPlugin, p as UPDATE_CODEBLOCK_LANG, q as charToId, r as SlashMenu, s as INSERT_MENTION_COMMAND, t as ReactSlashPlugin, u as useLexicalNodeSelection, v as registerCheckList, w as registerCodeInlineCommand, x as sanitizeUrl, y as extractUrlFromText, z as INSERT_MARKDOWN_COMMAND } from "./ReactSlashPlugin-BiVy_Iwf.js";
5
+ 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-DMdPzCo-.js";
6
+ import { ActionIcon, ActionIconGroup, Block, Button, Center, Dropdown, Flexbox, Hotkey, Icon, Input, LOBE_THEME_APP_ID, MaterialFileTypeIcon, Popover, Text, TextArea } from "@lobehub/ui";
7
+ import { BaselineIcon, Check, ChevronDown, EditIcon, ExternalLinkIcon, Grid2X2XIcon, GripVerticalIcon, LinkIcon, LoaderCircleIcon, PanelBottomCloseIcon, PanelLeftCloseIcon, PanelRightCloseIcon, PanelTopCloseIcon, PlusIcon, TableColumnsSplitIcon, TableRowsSplitIcon, UnlinkIcon, UploadIcon, X } from "lucide-react";
8
+ import { Suspense, forwardRef, memo, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
9
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
+ import { createStaticStyles, cssVar, cx, useThemeMode } from "antd-style";
11
+ import { Button as Button$1, Dropdown as Dropdown$1, theme } from "antd";
4
12
  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
13
  import { debounce } from "es-toolkit/compat";
6
14
  import EventEmitter from "eventemitter3";
7
15
  import { $createNodeSelection, $createParagraphNode, $createRangeSelection, $createTextNode, $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode$1, $getNodeByKey, $getPreviousSelection, $getRoot, $getSelection, $insertNodes, $isBlockElementNode, $isDecoratorNode, $isElementNode, $isNodeSelection, $isParagraphNode, $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
16
  import { DRAG_DROP_PASTE } from "@lexical/rich-text";
9
17
  import { $filter, $findMatchingParent, $getNearestBlockElementAncestorOrThrow, $getNearestNodeOfType, $insertNodeToNearestRoot, $wrapNodeInElement, addClassNamesToElement, calculateZoomLevel, mergeRegister, removeClassNamesFromElement } from "@lexical/utils";
10
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
11
- import { Suspense, forwardRef, memo, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState } from "react";
12
18
  import { $createListItemNode, $createListNode, $isListItemNode, $isListNode, INSERT_ORDERED_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND as INSERT_ORDERED_LIST_COMMAND$1, INSERT_UNORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND as INSERT_UNORDERED_LIST_COMMAND$1, ListItemNode, ListNode, REMOVE_LIST_COMMAND, UPDATE_LIST_START_COMMAND, registerList, registerListStrictIndentTransform } from "@lexical/list";
13
19
  import { DOMParser } from "@xmldom/xmldom";
14
20
  import katex, { renderToString } from "katex";
15
21
  import { $isCodeHighlightNode, $isCodeNode, CodeHighlightNode, CodeNode } from "@lexical/code-core";
16
- import { ActionIcon, ActionIconGroup, Block, Button, Center, Dropdown, Flexbox, Hotkey, Icon, Input, InputNumber, LOBE_THEME_APP_ID, MaterialFileTypeIcon, Popover, Select, Text, TextArea } from "@lobehub/ui";
17
- import { createStaticStyles, cssVar, cx, useThemeMode } from "antd-style";
18
- import { BaselineIcon, Check, ChevronDown, ChevronRight, CopyIcon, EditIcon, ExternalLinkIcon, Grid2X2XIcon, GripVerticalIcon, LinkIcon, LoaderCircleIcon, MoreHorizontalIcon, PanelBottomCloseIcon, PanelLeftCloseIcon, PanelRightCloseIcon, PanelTopCloseIcon, PlusIcon, TableColumnsSplitIcon, TableRowsSplitIcon, UnlinkIcon, UploadIcon, X } from "lucide-react";
19
22
  import { createPortal } from "react-dom";
20
- import { Button as Button$1, Dropdown as Dropdown$1, Switch, message, theme } from "antd";
21
23
  import { computePosition, flip, offset, shift } from "@floating-ui/dom";
22
24
  //#region src/editor-kernel/react/PortalContainer.tsx
23
25
  const LexicalPortalContainer = forwardRef(({ editor, node, children }, ref) => {
@@ -46,7 +48,7 @@ init_helper();
46
48
  init_hotkey();
47
49
  init_plugin();
48
50
  init_debug();
49
- const logger$10 = createDebugLogger("plugin", "litexml");
51
+ const logger$9 = createDebugLogger("plugin", "litexml");
50
52
  function toArrayXml(litexml) {
51
53
  return Array.isArray(litexml) ? litexml : [litexml];
52
54
  }
@@ -58,7 +60,7 @@ function tryParseChild(child, editor) {
58
60
  oldNode
59
61
  };
60
62
  } catch (error) {
61
- logger$10.error("❌ Error parsing child node:", error);
63
+ logger$9.error("❌ Error parsing child node:", error);
62
64
  return {
63
65
  newNode: null,
64
66
  oldNode: null
@@ -171,12 +173,12 @@ function registerLiteXMLCommand(editor, dataSource) {
171
173
  delay: true
172
174
  }, dataSource);
173
175
  break;
174
- default: logger$10.warn(`⚠️ Unknown action type: ${action}`);
176
+ default: logger$9.warn(`⚠️ Unknown action type: ${action}`);
175
177
  }
176
178
  });
177
179
  return false;
178
180
  } catch (error) {
179
- logger$10.error("❌ Error processing LITEXML_MODIFY_COMMAND:", error);
181
+ logger$9.error("❌ Error processing LITEXML_MODIFY_COMMAND:", error);
180
182
  return false;
181
183
  }
182
184
  }, COMMAND_PRIORITY_EDITOR), editor.registerCommand(LITEXML_APPLY_COMMAND, (payload) => {
@@ -201,9 +203,9 @@ function handleModify(editor, dataSource, arrayXml, delay) {
201
203
  try {
202
204
  const { oldNode, newNode } = tryParseChild(child, editor);
203
205
  if (oldNode && newNode) handleReplaceForApplyDelay(oldNode, newNode, modifyBlockNodes, diffNodeMap, editor);
204
- else logger$10.warn(`⚠️ Node with key ${child.id} not found for diffing.`);
206
+ else logger$9.warn(`⚠️ Node with key ${child.id} not found for diffing.`);
205
207
  } catch (error) {
206
- logger$10.error("❌ Error replacing node:", error);
208
+ logger$9.error("❌ Error replacing node:", error);
207
209
  }
208
210
  });
209
211
  });
@@ -227,7 +229,7 @@ function handleModify(editor, dataSource, arrayXml, delay) {
227
229
  } else prevNode = prevNode.insertAfter(newNode);
228
230
  else $insertNodes([newNode]);
229
231
  } catch (error) {
230
- logger$10.error("❌ Error replacing node:", error);
232
+ logger$9.error("❌ Error replacing node:", error);
231
233
  }
232
234
  });
233
235
  });
@@ -364,7 +366,7 @@ function handleInsert(editor, payload, dataSource) {
364
366
  });
365
367
  }
366
368
  } catch (error) {
367
- logger$10.error("❌ Error inserting node:", error);
369
+ logger$9.error("❌ Error inserting node:", error);
368
370
  }
369
371
  });
370
372
  }
@@ -474,7 +476,7 @@ ReactNodePlugin.displayName = "ReactNodePlugin";
474
476
  //#endregion
475
477
  //#region src/plugins/litexml/data-source/litexml-data-source.ts
476
478
  init_debug();
477
- const logger$9 = createDebugLogger("plugin", "litexml");
479
+ const logger$8 = createDebugLogger("plugin", "litexml");
478
480
  var IXmlWriterContext = class {
479
481
  createXmlNode(tagName, attributes, textContent) {
480
482
  return {
@@ -502,7 +504,7 @@ var LitexmlDataSource = class extends DataSource {
502
504
  const xml = this.parseXMLString(litexml);
503
505
  const inode = this.xmlToLexical(xml);
504
506
  this.getService?.(INodeService)?.processNodeTree(inode);
505
- logger$9.debug("Parsed XML to Lexical State:", inode);
507
+ logger$8.debug("Parsed XML to Lexical State:", inode);
506
508
  return inode;
507
509
  }
508
510
  /**
@@ -523,7 +525,7 @@ var LitexmlDataSource = class extends DataSource {
523
525
  });
524
526
  editor.setEditorState(newState);
525
527
  } catch (error) {
526
- logger$9.error("Failed to parse XML:", error);
528
+ logger$8.error("Failed to parse XML:", error);
527
529
  throw error;
528
530
  }
529
531
  }
@@ -558,7 +560,7 @@ var LitexmlDataSource = class extends DataSource {
558
560
  return this.lexicalToXML(rootNode);
559
561
  });
560
562
  } catch (error) {
561
- logger$9.error("Failed to export to XML:", error);
563
+ logger$8.error("Failed to export to XML:", error);
562
564
  throw error;
563
565
  }
564
566
  }
@@ -873,7 +875,7 @@ const LitexmlPlugin = class extends KernelPlugin {
873
875
  };
874
876
  //#endregion
875
877
  //#region src/plugins/litexml/react/DiffNodeToolbar/style.ts
876
- const styles$15 = createStaticStyles(({ css, cssVar }) => ({
878
+ const styles$13 = createStaticStyles(({ css, cssVar }) => ({
877
879
  accept: css`
878
880
  color: ${cssVar.colorSuccess};
879
881
  `,
@@ -902,7 +904,7 @@ const ReactDiffNodeToolbar = ({ editor, node }) => {
902
904
  editor,
903
905
  node,
904
906
  children: /* @__PURE__ */ jsxs(Block, {
905
- className: isDarkMode ? styles$15.toolbarDark : styles$15.toolbarLight,
907
+ className: isDarkMode ? styles$13.toolbarDark : styles$13.toolbarLight,
906
908
  gap: 2,
907
909
  horizontal: true,
908
910
  padding: 2,
@@ -910,7 +912,7 @@ const ReactDiffNodeToolbar = ({ editor, node }) => {
910
912
  variant: "outlined",
911
913
  children: [/* @__PURE__ */ jsx(ActionIcon, {
912
914
  "aria-label": "Reject change",
913
- className: styles$15.reject,
915
+ className: styles$13.reject,
914
916
  danger: true,
915
917
  icon: X,
916
918
  onClick: () => {
@@ -926,7 +928,7 @@ const ReactDiffNodeToolbar = ({ editor, node }) => {
926
928
  title: t("modifier.reject")
927
929
  }), /* @__PURE__ */ jsx(ActionIcon, {
928
930
  "aria-label": "Accept change",
929
- className: styles$15.accept,
931
+ className: styles$13.accept,
930
932
  icon: Check,
931
933
  onClick: () => {
932
934
  editor.dispatchCommand(LITEXML_DIFFNODE_COMMAND, {
@@ -946,7 +948,7 @@ const ReactDiffNodeToolbar = ({ editor, node }) => {
946
948
  ReactDiffNodeToolbar.displayName = "ReactDiffNodeToolbar";
947
949
  //#endregion
948
950
  //#region src/plugins/litexml/react/style.ts
949
- const styles$14 = createStaticStyles(({ css, cssVar }) => css`
951
+ const styles$12 = createStaticStyles(({ css, cssVar }) => css`
950
952
  position: relative;
951
953
 
952
954
  .toolbar {
@@ -1077,7 +1079,7 @@ const ReactLiteXmlPlugin = () => {
1077
1079
  editor,
1078
1080
  node
1079
1081
  }),
1080
- theme: styles$14
1082
+ theme: styles$12
1081
1083
  });
1082
1084
  }, [editor]);
1083
1085
  return null;
@@ -2095,6 +2097,54 @@ const HeadlessCodeblockPlugin = class extends KernelPlugin {
2095
2097
  }
2096
2098
  };
2097
2099
  //#endregion
2100
+ //#region src/headless/extract-media-from-editor-state.ts
2101
+ const IMAGE_TYPES = new Set(["image", "block-image"]);
2102
+ const FILE_TYPE = "file";
2103
+ const generateId$1 = () => {
2104
+ if (typeof globalThis.crypto?.randomUUID === "function") return globalThis.crypto.randomUUID();
2105
+ return `id-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`;
2106
+ };
2107
+ const inferFileType$1 = (name) => {
2108
+ const dotIndex = name.lastIndexOf(".");
2109
+ if (dotIndex < 0 || dotIndex === name.length - 1) return "unknown";
2110
+ return name.slice(dotIndex + 1).toLowerCase() || "unknown";
2111
+ };
2112
+ const extractMediaFromEditorState = (state) => {
2113
+ const imageList = [];
2114
+ const fileList = [];
2115
+ const visit = (node) => {
2116
+ const type = node.type;
2117
+ if (IMAGE_TYPES.has(type)) {
2118
+ if (node.status === "uploaded" && typeof node.src === "string" && node.src) imageList.push({
2119
+ alt: typeof node.altText === "string" ? node.altText : "",
2120
+ id: generateId$1(),
2121
+ url: node.src
2122
+ });
2123
+ return;
2124
+ }
2125
+ if (type === FILE_TYPE) {
2126
+ if (node.status === "uploaded" && typeof node.fileUrl === "string" && node.fileUrl) {
2127
+ const name = typeof node.name === "string" ? node.name : "unknown";
2128
+ fileList.push({
2129
+ fileType: inferFileType$1(name),
2130
+ id: generateId$1(),
2131
+ name,
2132
+ size: typeof node.size === "number" ? node.size : 0,
2133
+ url: node.fileUrl
2134
+ });
2135
+ }
2136
+ return;
2137
+ }
2138
+ if (Array.isArray(node.children)) for (const child of node.children) visit(child);
2139
+ };
2140
+ const root = state?.root;
2141
+ if (root && Array.isArray(root.children)) for (const child of root.children) visit(child);
2142
+ return {
2143
+ fileList,
2144
+ imageList
2145
+ };
2146
+ };
2147
+ //#endregion
2098
2148
  //#region src/headless/index.ts
2099
2149
  const getNumericId = (id) => {
2100
2150
  if (typeof id !== "number" && typeof id !== "string") return null;
@@ -2660,7 +2710,7 @@ const AutoCompletePlugin = class extends KernelPlugin {
2660
2710
  };
2661
2711
  //#endregion
2662
2712
  //#region src/plugins/auto-complete/react/style.ts
2663
- const styles$13 = createStaticStyles(({ css }) => ({
2713
+ const styles$11 = createStaticStyles(({ css }) => ({
2664
2714
  placeholderBlock: css`
2665
2715
  opacity: 0.4;
2666
2716
  `,
@@ -2671,7 +2721,7 @@ const styles$13 = createStaticStyles(({ css }) => ({
2671
2721
  //#endregion
2672
2722
  //#region src/plugins/auto-complete/react/ReactAutoCompletePlugin.tsx
2673
2723
  init_debug();
2674
- const logger$8 = createDebugLogger("react-plugin", "auto-complete");
2724
+ const logger$7 = createDebugLogger("react-plugin", "auto-complete");
2675
2725
  const ReactAutoCompletePlugin = ({ delay, onAutoComplete, onSuggestionAccepted, onSuggestionRejected }) => {
2676
2726
  const [editor] = useLexicalComposerContext();
2677
2727
  const propsRef = useRef({
@@ -2693,7 +2743,7 @@ const ReactAutoCompletePlugin = ({ delay, onAutoComplete, onSuggestionAccepted,
2693
2743
  try {
2694
2744
  return await propsRef.current.onAutoComplete?.(opt) ?? null;
2695
2745
  } catch (error) {
2696
- logger$8.warn("Auto-complete onAutoComplete callback failed:", error);
2746
+ logger$7.warn("Auto-complete onAutoComplete callback failed:", error);
2697
2747
  return null;
2698
2748
  }
2699
2749
  },
@@ -2701,19 +2751,19 @@ const ReactAutoCompletePlugin = ({ delay, onAutoComplete, onSuggestionAccepted,
2701
2751
  try {
2702
2752
  propsRef.current.onSuggestionAccepted?.(info);
2703
2753
  } catch (error) {
2704
- logger$8.warn("Auto-complete onSuggestionAccepted callback failed:", error);
2754
+ logger$7.warn("Auto-complete onSuggestionAccepted callback failed:", error);
2705
2755
  }
2706
2756
  },
2707
2757
  onSuggestionRejected: (info) => {
2708
2758
  try {
2709
2759
  propsRef.current.onSuggestionRejected?.(info);
2710
2760
  } catch (error) {
2711
- logger$8.warn("Auto-complete onSuggestionRejected callback failed:", error);
2761
+ logger$7.warn("Auto-complete onSuggestionRejected callback failed:", error);
2712
2762
  }
2713
2763
  },
2714
2764
  theme: {
2715
- placeholderBlock: cx(styles$13.placeholderBlock),
2716
- placeholderInline: cx(styles$13.placeholderInline)
2765
+ placeholderBlock: cx(styles$11.placeholderBlock),
2766
+ placeholderInline: cx(styles$11.placeholderInline)
2717
2767
  }
2718
2768
  });
2719
2769
  }, []);
@@ -2724,7 +2774,7 @@ ReactAutoCompletePlugin.displayName = "ReactAutoCompletePlugin";
2724
2774
  //#region src/plugins/block/command/index.ts
2725
2775
  init_debug();
2726
2776
  const MOVE_BLOCK_COMMAND = createCommand("MOVE_BLOCK_COMMAND");
2727
- const logger$7 = createDebugLogger("plugin", "block-command");
2777
+ const logger$6 = createDebugLogger("plugin", "block-command");
2728
2778
  const getListParent = (node) => {
2729
2779
  if (!node) return null;
2730
2780
  const parent = node.getParent();
@@ -2764,24 +2814,24 @@ const cleanupEmptyListForItem = (listItem) => {
2764
2814
  if (parentList && parentList.getChildrenSize() === 0) parentList.remove();
2765
2815
  };
2766
2816
  const moveBlockNode = (payload) => {
2767
- logger$7.debug("start", payload);
2817
+ logger$6.debug("start", payload);
2768
2818
  const sourceNode = $getNodeByKey(payload.sourceBlockId);
2769
2819
  const targetNode = $getNodeByKey(payload.targetBlockId);
2770
2820
  if (!sourceNode || !targetNode) {
2771
- logger$7.debug("abort: node-not-found", {
2821
+ logger$6.debug("abort: node-not-found", {
2772
2822
  sourceFound: Boolean(sourceNode),
2773
2823
  targetFound: Boolean(targetNode)
2774
2824
  });
2775
2825
  return;
2776
2826
  }
2777
2827
  if (sourceNode === targetNode) {
2778
- logger$7.debug("abort: source-equals-target");
2828
+ logger$6.debug("abort: source-equals-target");
2779
2829
  return;
2780
2830
  }
2781
2831
  if (!$isListItemNode(targetNode)) {
2782
2832
  const sourceIsListItem = $isListItemNode(sourceNode);
2783
2833
  let movingNode = sourceNode;
2784
- logger$7.debug("branch: normal-block-target", {
2834
+ logger$6.debug("branch: normal-block-target", {
2785
2835
  placement: payload.placement,
2786
2836
  targetType: targetNode.getType()
2787
2837
  });
@@ -2792,18 +2842,18 @@ const moveBlockNode = (payload) => {
2792
2842
  sourceListItem.remove();
2793
2843
  cleanupEmptyListForItem(sourceListItem);
2794
2844
  movingNode = paragraphNode;
2795
- logger$7.debug("convert: listItem-to-paragraph", { sourceType: sourceNode.getType() });
2845
+ logger$6.debug("convert: listItem-to-paragraph", { sourceType: sourceNode.getType() });
2796
2846
  }
2797
2847
  if (payload.placement === "before") targetNode.insertBefore(movingNode);
2798
2848
  else targetNode.insertAfter(movingNode);
2799
- logger$7.debug("done: normal-block-target");
2849
+ logger$6.debug("done: normal-block-target");
2800
2850
  return;
2801
2851
  }
2802
2852
  const targetListItem = targetNode;
2803
2853
  const sourceIsListItem = $isListItemNode(sourceNode);
2804
2854
  const sourceIsParagraph = $isParagraphNode(sourceNode);
2805
2855
  if (sourceIsListItem || sourceIsParagraph) {
2806
- logger$7.debug("branch: list-insert-with-item-or-paragraph", {
2856
+ logger$6.debug("branch: list-insert-with-item-or-paragraph", {
2807
2857
  sourceIsListItem,
2808
2858
  sourceIsParagraph,
2809
2859
  targetType: targetListItem.getType()
@@ -2822,35 +2872,35 @@ const moveBlockNode = (payload) => {
2822
2872
  alignListItemDepth(movingListItem, targetListItem);
2823
2873
  if (payload.placement === "before") targetListItem.insertBefore(movingListItem);
2824
2874
  else targetListItem.insertAfter(movingListItem);
2825
- logger$7.debug("done: list-insert-with-item-or-paragraph");
2875
+ logger$6.debug("done: list-insert-with-item-or-paragraph");
2826
2876
  return;
2827
2877
  }
2828
2878
  const topContext = getTopListContextFromItem(targetListItem);
2829
2879
  const topListNode = topContext.list;
2830
2880
  const topListItem = topContext.item;
2831
2881
  if (!topListNode) {
2832
- logger$7.debug("branch: list-target-without-top-list", { placement: payload.placement });
2882
+ logger$6.debug("branch: list-target-without-top-list", { placement: payload.placement });
2833
2883
  if (payload.placement === "before") targetListItem.insertBefore(sourceNode);
2834
2884
  else targetListItem.insertAfter(sourceNode);
2835
- logger$7.debug("done: list-target-without-top-list");
2885
+ logger$6.debug("done: list-target-without-top-list");
2836
2886
  return;
2837
2887
  }
2838
2888
  const tailStart = payload.placement === "before" ? topListItem : topListItem.getNextSibling();
2839
2889
  if (tailStart === topListItem && topListItem.getPreviousSibling() === null) {
2840
- logger$7.debug("branch: split-list-head-insert-before-list");
2890
+ logger$6.debug("branch: split-list-head-insert-before-list");
2841
2891
  topListNode.insertBefore(sourceNode);
2842
- logger$7.debug("done: split-list-head-insert-before-list");
2892
+ logger$6.debug("done: split-list-head-insert-before-list");
2843
2893
  return;
2844
2894
  }
2845
2895
  if (!tailStart) {
2846
- logger$7.debug("branch: split-list-tail-insert-after-list");
2896
+ logger$6.debug("branch: split-list-tail-insert-after-list");
2847
2897
  topListNode.insertAfter(sourceNode);
2848
- logger$7.debug("done: split-list-tail-insert-after-list");
2898
+ logger$6.debug("done: split-list-tail-insert-after-list");
2849
2899
  return;
2850
2900
  }
2851
2901
  const listStartValue = $isListItemNode(tailStart) && typeof tailStart.getValue === "function" ? tailStart.getValue() : 1;
2852
2902
  const newTailList = cloneListTail(topListNode, tailStart, listStartValue);
2853
- logger$7.debug("branch: split-list-middle", {
2903
+ logger$6.debug("branch: split-list-middle", {
2854
2904
  hasNewTailList: Boolean(newTailList),
2855
2905
  listStartValue,
2856
2906
  tailStartType: tailStart.getType()
@@ -2865,11 +2915,11 @@ const moveBlockNode = (payload) => {
2865
2915
  if (parentList && parentList.getChildrenSize() === 0) parentList.remove();
2866
2916
  }
2867
2917
  }
2868
- logger$7.debug("done: split-list-middle");
2918
+ logger$6.debug("done: split-list-middle");
2869
2919
  };
2870
2920
  function registerBlockMoveCommand(editor) {
2871
2921
  const unregister = editor.registerCommand(MOVE_BLOCK_COMMAND, (payload) => {
2872
- logger$7.debug("received-command", payload);
2922
+ logger$6.debug("received-command", payload);
2873
2923
  moveBlockNode(payload);
2874
2924
  return true;
2875
2925
  }, COMMAND_PRIORITY_EDITOR);
@@ -3073,7 +3123,7 @@ const resolveNearestInsertionSlot = (sourceBlockId, blocks, y) => {
3073
3123
  //#endregion
3074
3124
  //#region src/plugins/block/react/drag/drag-session.ts
3075
3125
  init_debug();
3076
- const logger$6 = createDebugLogger("plugin", "block-react");
3126
+ const logger$5 = createDebugLogger("plugin", "block-react");
3077
3127
  const DRAG_GHOST_OFFSET_X = 14;
3078
3128
  const DRAG_GHOST_OFFSET_Y = 14;
3079
3129
  const DRAG_SOURCE_OPACITY = "0.45";
@@ -3238,13 +3288,13 @@ const startBlockDragSession = ({ clientX, clientY, clearDragPreview, contextRef,
3238
3288
  }
3239
3289
  const finalTarget = contextRef.current.dragTarget;
3240
3290
  if (finalTarget) {
3241
- logger$6.debug("drag-end", {
3291
+ logger$5.debug("drag-end", {
3242
3292
  位置: finalTarget.placement === "before" ? "上方" : "下方",
3243
3293
  位置节点id: finalTarget.targetBlockId,
3244
3294
  插入节点id: finalTarget.sourceBlockId
3245
3295
  });
3246
3296
  const handled = editor.dispatchCommand(MOVE_BLOCK_COMMAND, finalTarget);
3247
- logger$6.debug("move-block-command-handled", handled);
3297
+ logger$5.debug("move-block-command-handled", handled);
3248
3298
  }
3249
3299
  onDragTargetResolve?.(contextRef.current.dragTarget);
3250
3300
  if (contextRef.current.dragRaf !== null) {
@@ -3332,7 +3382,7 @@ const startBlockDragSession = ({ clientX, clientY, clearDragPreview, contextRef,
3332
3382
  };
3333
3383
  //#endregion
3334
3384
  //#region src/plugins/block/react/style.ts
3335
- const styles$12 = createStaticStyles(({ css, cssVar }) => ({
3385
+ const styles$10 = createStaticStyles(({ css, cssVar }) => ({
3336
3386
  dragHandle: css`
3337
3387
  cursor: grab !important;
3338
3388
 
@@ -3397,13 +3447,13 @@ const styles$12 = createStaticStyles(({ css, cssVar }) => ({
3397
3447
  //#endregion
3398
3448
  //#region src/plugins/block/react/ReactBlockPlugin.tsx
3399
3449
  init_debug();
3400
- const logger$5 = createDebugLogger("plugin", "block-react");
3450
+ const logger$4 = createDebugLogger("plugin", "block-react");
3401
3451
  const OPERATION_MENU_OVERLAY_CLASS = "lobe-block-operation-dropdown";
3402
3452
  const ReactBlockPlugin = (props) => {
3403
3453
  const { token } = theme.useToken();
3404
3454
  const [editor] = useLexicalComposerContext();
3405
3455
  const { rootClassName, className, attributeName, locale, onHoverBlockChange, onDragTargetChange, onDragTargetResolve } = props;
3406
- const mergedRootClassName = cx(styles$12.root, rootClassName?.trim() || className?.trim());
3456
+ const mergedRootClassName = cx(styles$10.root, rootClassName?.trim() || className?.trim());
3407
3457
  const menuRef = useRef(null);
3408
3458
  const dragLayerRef = useRef(null);
3409
3459
  const contextRef = useRef(createRuntimeContext());
@@ -3431,7 +3481,7 @@ const ReactBlockPlugin = (props) => {
3431
3481
  useLexicalEditor(() => {
3432
3482
  const service = editor.requireService(IBlockMenuService);
3433
3483
  if (!service) {
3434
- logger$5.warn("BlockMenuService not found");
3484
+ logger$4.warn("BlockMenuService not found");
3435
3485
  return;
3436
3486
  }
3437
3487
  setBlockMenuService(service);
@@ -3767,11 +3817,11 @@ const ReactBlockPlugin = (props) => {
3767
3817
  })), [operationMenus, operationMenuContext]);
3768
3818
  const shouldRenderPortal = menuContext || dragIndicator;
3769
3819
  const menuNode = menuContext && !isDragging ? /* @__PURE__ */ jsx("div", {
3770
- className: styles$12.menu,
3820
+ className: styles$10.menu,
3771
3821
  ref: menuRef,
3772
3822
  style: menuPosition,
3773
3823
  children: /* @__PURE__ */ jsxs("div", {
3774
- className: styles$12.menuInner,
3824
+ className: styles$10.menuInner,
3775
3825
  onMouseDown: preventEditorSelectionLost,
3776
3826
  children: [actionButtons.map((item) => {
3777
3827
  const title = typeof item.title === "function" ? item.title(menuContext) : item.title;
@@ -3801,7 +3851,7 @@ const ReactBlockPlugin = (props) => {
3801
3851
  trigger: [],
3802
3852
  children: /* @__PURE__ */ jsx(Button$1, {
3803
3853
  "aria-label": "Block actions and drag",
3804
- className: styles$12.dragHandle,
3854
+ className: styles$10.dragHandle,
3805
3855
  "data-block-drag-handle": "true",
3806
3856
  icon: /* @__PURE__ */ jsx(Icon, {
3807
3857
  icon: GripVerticalIcon,
@@ -3818,12 +3868,12 @@ const ReactBlockPlugin = (props) => {
3818
3868
  }) : null;
3819
3869
  const dragLayerNode = /* @__PURE__ */ jsx("div", {
3820
3870
  "aria-hidden": "true",
3821
- className: styles$12.dragLayer,
3871
+ className: styles$10.dragLayer,
3822
3872
  "data-block-drag-layer": "true",
3823
3873
  ref: dragLayerRef
3824
3874
  });
3825
3875
  return /* @__PURE__ */ jsxs(Fragment, { children: [dragLayerContainer ? createPortal(dragLayerNode, dragLayerContainer) : dragLayerNode, shouldRenderPortal && createPortal(/* @__PURE__ */ jsxs(Fragment, { children: [menuNode, dragIndicator && /* @__PURE__ */ jsx("div", {
3826
- className: styles$12.dragIndicator,
3876
+ className: styles$10.dragIndicator,
3827
3877
  style: {
3828
3878
  backgroundColor: token.colorPrimary,
3829
3879
  left: dragIndicator.left,
@@ -3835,7 +3885,7 @@ const ReactBlockPlugin = (props) => {
3835
3885
  ReactBlockPlugin.displayName = "ReactBlockPlugin";
3836
3886
  //#endregion
3837
3887
  //#region src/plugins/code/react/style.ts
3838
- const styles$11 = createStaticStyles(({ css, cssVar }) => ({ codeInline: css`
3888
+ const styles$9 = createStaticStyles(({ css, cssVar }) => ({ codeInline: css`
3839
3889
  display: inline;
3840
3890
 
3841
3891
  margin-inline: 0.25em;
@@ -3860,20 +3910,20 @@ const ReactCodePlugin = ({ className, enableHotkey = true }) => {
3860
3910
  editor.registerPlugin(MarkdownPlugin);
3861
3911
  editor.registerPlugin(CodePlugin, {
3862
3912
  enableHotkey,
3863
- theme: cx(styles$11.codeInline, className)
3913
+ theme: cx(styles$9.codeInline, className)
3864
3914
  });
3865
3915
  }, [
3866
3916
  className,
3867
3917
  cx,
3868
3918
  enableHotkey,
3869
- styles$11.codeInline
3919
+ styles$9.codeInline
3870
3920
  ]);
3871
3921
  return null;
3872
3922
  };
3873
3923
  ReactCodePlugin.displayName = "ReactCodePlugin";
3874
3924
  //#endregion
3875
3925
  //#region src/plugins/codeblock/react/style.ts
3876
- const styles$10 = createStaticStyles(({ css, cssVar }) => ({
3926
+ const styles$8 = createStaticStyles(({ css, cssVar }) => ({
3877
3927
  code: css`
3878
3928
  position: relative;
3879
3929
 
@@ -3935,10 +3985,10 @@ const ReactCodeblockPlugin = ({ theme, shikiTheme }) => {
3935
3985
  editor.registerPlugin(MarkdownPlugin);
3936
3986
  editor.registerPlugin(CodeblockPlugin, {
3937
3987
  shikiTheme: shikiTheme || "lobe-theme",
3938
- theme: theme || { code: styles$10.code }
3988
+ theme: theme || { code: styles$8.code }
3939
3989
  });
3940
3990
  }, [
3941
- cx(styles$10.code),
3991
+ cx(styles$8.code),
3942
3992
  editor,
3943
3993
  shikiTheme,
3944
3994
  theme
@@ -4010,518 +4060,9 @@ function registerCodeMirrorCommand(editor) {
4010
4060
  }
4011
4061
  //#endregion
4012
4062
  //#region src/plugins/codemirror-block/lib/mode.ts
4013
- const MODES = [
4014
- {
4015
- ext: ["agda"],
4016
- name: "Agda",
4017
- syntax: "text/x-agda",
4018
- value: "agda"
4019
- },
4020
- {
4021
- ext: ["ets", "arkts"],
4022
- name: "ArkTS",
4023
- syntax: "text/x-arkts",
4024
- value: "arkts"
4025
- },
4026
- {
4027
- ext: ["bash"],
4028
- name: "Bash",
4029
- syntax: "shell",
4030
- value: "bash"
4031
- },
4032
- {
4033
- ext: ["vbs"],
4034
- name: "Basic",
4035
- syntax: "vbscript",
4036
- value: "basic"
4037
- },
4038
- {
4039
- ext: [
4040
- "c",
4041
- "h",
4042
- "ino"
4043
- ],
4044
- name: "C",
4045
- syntax: "text/x-csrc",
4046
- value: "c"
4047
- },
4048
- {
4049
- ext: [
4050
- "cpp",
4051
- "c++",
4052
- "cc",
4053
- "cxx",
4054
- "hpp",
4055
- "h++",
4056
- "hh",
4057
- "hxx"
4058
- ],
4059
- name: "C++",
4060
- syntax: "text/x-c++src",
4061
- value: "cpp"
4062
- },
4063
- {
4064
- ext: ["cs"],
4065
- name: "C#",
4066
- syntax: "text/x-csharp",
4067
- value: "csharp"
4068
- },
4069
- {
4070
- ext: ["css"],
4071
- name: "CSS",
4072
- syntax: "css",
4073
- value: "css"
4074
- },
4075
- {
4076
- ext: ["dart"],
4077
- name: "Dart",
4078
- syntax: "dart",
4079
- value: "dart"
4080
- },
4081
- {
4082
- ext: ["diff", "patch"],
4083
- name: "Diff",
4084
- syntax: "diff",
4085
- value: "diff"
4086
- },
4087
- {
4088
- name: "Dockerfile",
4089
- syntax: "dockerfile",
4090
- value: "dockerfile"
4091
- },
4092
- {
4093
- ext: ["erl"],
4094
- name: "Erlang",
4095
- syntax: "erlang",
4096
- value: "erlang"
4097
- },
4098
- {
4099
- ext: ["glsl"],
4100
- name: "Glsl",
4101
- syntax: "x-shader/x-vertex",
4102
- value: "glsl"
4103
- },
4104
- {
4105
- name: "Git",
4106
- syntax: "shell",
4107
- value: "git"
4108
- },
4109
- {
4110
- ext: ["go"],
4111
- name: "Go",
4112
- syntax: "go",
4113
- value: "go"
4114
- },
4115
- {
4116
- name: "GraphQL",
4117
- syntax: "graphql",
4118
- value: "graphql"
4119
- },
4120
- {
4121
- ext: ["groovy", "gradle"],
4122
- name: "Groovy",
4123
- syntax: "groovy",
4124
- value: "groovy"
4125
- },
4126
- {
4127
- ext: [
4128
- "html",
4129
- "htm",
4130
- "handlebars",
4131
- "hbs"
4132
- ],
4133
- name: "HTML",
4134
- syntax: "htmlmixed",
4135
- value: "html"
4136
- },
4137
- {
4138
- name: "HTTP",
4139
- syntax: "http",
4140
- value: "http"
4141
- },
4142
- {
4143
- ext: ["java"],
4144
- name: "Java",
4145
- syntax: "text/x-java",
4146
- value: "java"
4147
- },
4148
- {
4149
- ext: ["js"],
4150
- name: "JavaScript",
4151
- syntax: "text/javascript",
4152
- value: "javascript"
4153
- },
4154
- {
4155
- ext: ["json", "map"],
4156
- name: "JSON",
4157
- syntax: "application/json",
4158
- value: "json"
4159
- },
4160
- {
4161
- ext: ["jsx"],
4162
- name: "JSX",
4163
- syntax: "jsx",
4164
- value: "jsx"
4165
- },
4166
- {
4167
- name: "KaTeX",
4168
- syntax: "simplemode",
4169
- value: "katex"
4170
- },
4171
- {
4172
- ext: ["kt"],
4173
- name: "Kotlin",
4174
- syntax: "text/x-kotlin",
4175
- value: "kotlin"
4176
- },
4177
- {
4178
- ext: ["less"],
4179
- name: "Less",
4180
- syntax: "css",
4181
- value: "less"
4182
- },
4183
- {
4184
- name: "Makefile",
4185
- syntax: "cmake",
4186
- value: "makefile"
4187
- },
4188
- {
4189
- ext: [
4190
- "markdown",
4191
- "md",
4192
- "mkd"
4193
- ],
4194
- name: "Markdown",
4195
- syntax: "markdown",
4196
- value: "markdown"
4197
- },
4198
- {
4199
- name: "MATLAB",
4200
- syntax: "octave",
4201
- value: "matlab"
4202
- },
4203
- {
4204
- ext: ["conf"],
4205
- name: "Nginx",
4206
- syntax: "nginx",
4207
- value: "nginx"
4208
- },
4209
- {
4210
- ext: ["m"],
4211
- name: "Objective-C",
4212
- syntax: "text/x-objectivec",
4213
- value: "objectivec"
4214
- },
4215
- {
4216
- ext: ["p", "pas"],
4217
- name: "Pascal",
4218
- syntax: "pascal",
4219
- value: "pascal"
4220
- },
4221
- {
4222
- ext: ["pl", "pm"],
4223
- name: "Perl",
4224
- syntax: "perl",
4225
- value: "perl"
4226
- },
4227
- {
4228
- ext: [
4229
- "php",
4230
- "php3",
4231
- "php4",
4232
- "php5",
4233
- "php7",
4234
- "phtml"
4235
- ],
4236
- name: "PHP",
4237
- syntax: "text/x-php",
4238
- value: "php"
4239
- },
4240
- {
4241
- ext: [
4242
- "ps1",
4243
- "psd1",
4244
- "psm1"
4245
- ],
4246
- name: "PowerShell",
4247
- syntax: "powershell",
4248
- value: "powershell"
4249
- },
4250
- {
4251
- ext: ["proto"],
4252
- name: "Protobuf",
4253
- syntax: "protobuf",
4254
- value: "protobuf"
4255
- },
4256
- {
4257
- ext: [
4258
- "build",
4259
- "bzl",
4260
- "py",
4261
- "pyw"
4262
- ],
4263
- name: "Python",
4264
- syntax: "python",
4265
- value: "python"
4266
- },
4267
- {
4268
- ext: ["r", "R"],
4269
- name: "R",
4270
- syntax: "r",
4271
- value: "r"
4272
- },
4273
- {
4274
- ext: ["rb"],
4275
- name: "Ruby",
4276
- syntax: "ruby",
4277
- value: "ruby"
4278
- },
4279
- {
4280
- ext: ["rs"],
4281
- name: "Rust",
4282
- syntax: "rust",
4283
- value: "rust"
4284
- },
4285
- {
4286
- ext: ["scala"],
4287
- name: "Scala",
4288
- syntax: "text/x-scala",
4289
- value: "scala"
4290
- },
4291
- {
4292
- ext: ["sh", "ksh"],
4293
- name: "Shell",
4294
- syntax: "shell",
4295
- value: "shell"
4296
- },
4297
- {
4298
- ext: ["sql"],
4299
- name: "SQL",
4300
- syntax: "text/x-sql",
4301
- value: "sql"
4302
- },
4303
- {
4304
- name: "PL/SQL",
4305
- syntax: "text/x-plsql",
4306
- value: "plsql"
4307
- },
4308
- {
4309
- ext: ["swift"],
4310
- name: "Swift",
4311
- syntax: "swift",
4312
- value: "swift"
4313
- },
4314
- {
4315
- ext: ["ts"],
4316
- name: "TypeScript",
4317
- syntax: "text/typescript",
4318
- value: "typescript"
4319
- },
4320
- {
4321
- ext: ["vb"],
4322
- name: "VB.net",
4323
- syntax: "vb",
4324
- value: "vbnet"
4325
- },
4326
- {
4327
- ext: ["vtl"],
4328
- name: "Velocity",
4329
- syntax: "velocity",
4330
- value: "velocity"
4331
- },
4332
- {
4333
- ext: [
4334
- "xml",
4335
- "xsl",
4336
- "xsd",
4337
- "svg"
4338
- ],
4339
- name: "XML",
4340
- syntax: "xml",
4341
- value: "xml"
4342
- },
4343
- {
4344
- ext: ["yaml", "yml"],
4345
- name: "YAML",
4346
- syntax: "yaml",
4347
- value: "yaml"
4348
- },
4349
- {
4350
- name: "sTeX",
4351
- syntax: "text/x-stex",
4352
- value: "stex"
4353
- },
4354
- {
4355
- ext: [
4356
- "text",
4357
- "ltx",
4358
- "tex"
4359
- ],
4360
- name: "LaTeX",
4361
- syntax: "text/x-latex",
4362
- value: "latex"
4363
- },
4364
- {
4365
- ext: ["sv", "svh"],
4366
- name: "SystemVerilog",
4367
- syntax: "text/x-systemverilog",
4368
- value: "systemverilog"
4369
- },
4370
- {
4371
- ext: ["sass", "scss"],
4372
- name: "Sass",
4373
- syntax: "text/x-sass",
4374
- value: "sass"
4375
- },
4376
- {
4377
- ext: ["tcl"],
4378
- name: "Tcl",
4379
- syntax: "text/x-tcl",
4380
- value: "tcl"
4381
- },
4382
- {
4383
- ext: ["v"],
4384
- name: "Verilog",
4385
- syntax: "text/x-verilog",
4386
- value: "verilog"
4387
- },
4388
- {
4389
- name: "Vue",
4390
- syntax: "text/x-vue",
4391
- value: "vue"
4392
- },
4393
- {
4394
- ext: ["lua"],
4395
- name: "Lua",
4396
- syntax: "text/x-lua",
4397
- value: "lua"
4398
- },
4399
- {
4400
- ext: ["hs"],
4401
- name: "Haskell",
4402
- syntax: "haskell",
4403
- value: "haskell"
4404
- },
4405
- {
4406
- ext: [
4407
- "properties",
4408
- "ini",
4409
- "in"
4410
- ],
4411
- name: "Properties",
4412
- syntax: "properties",
4413
- value: "properties"
4414
- },
4415
- {
4416
- ext: ["toml"],
4417
- name: "TOML",
4418
- syntax: "toml",
4419
- value: "toml"
4420
- },
4421
- {
4422
- ext: ["cyp", "cypher"],
4423
- name: "Cypher",
4424
- syntax: "cypher",
4425
- value: "cypher"
4426
- },
4427
- {
4428
- ext: ["tsx"],
4429
- name: "TSX",
4430
- syntax: "jsx",
4431
- value: "tsx"
4432
- },
4433
- {
4434
- ext: ["fs"],
4435
- name: "F#",
4436
- syntax: "mllike",
4437
- value: "f#"
4438
- },
4439
- {
4440
- ext: [
4441
- "ml",
4442
- "mli",
4443
- "mll",
4444
- "mly"
4445
- ],
4446
- name: "OCaml",
4447
- syntax: "mllike",
4448
- value: "ocaml"
4449
- },
4450
- {
4451
- ext: [
4452
- "clj",
4453
- "cljc",
4454
- "cljx"
4455
- ],
4456
- name: "Clojure",
4457
- syntax: "clojure",
4458
- value: "clojure"
4459
- },
4460
- {
4461
- name: "ABAP",
4462
- syntax: "abap",
4463
- value: "abap"
4464
- },
4465
- {
4466
- ext: ["jl"],
4467
- name: "Julia",
4468
- syntax: "julia",
4469
- value: "julia"
4470
- },
4471
- {
4472
- ext: ["cmake"],
4473
- name: "CMake",
4474
- syntax: "cmake",
4475
- value: "cmake"
4476
- },
4477
- {
4478
- ext: ["scm", "ss"],
4479
- name: "Scheme",
4480
- syntax: "scheme",
4481
- value: "scheme"
4482
- },
4483
- {
4484
- ext: [
4485
- "cl",
4486
- "lisp",
4487
- "el"
4488
- ],
4489
- name: "Lisp",
4490
- syntax: "commonlisp",
4491
- value: "commonlisp"
4492
- },
4493
- {
4494
- ext: [
4495
- "f90",
4496
- "f95",
4497
- "f03"
4498
- ],
4499
- name: "Fortran",
4500
- syntax: "fortran",
4501
- value: "fortran"
4502
- },
4503
- {
4504
- ext: ["sol"],
4505
- name: "Solidity",
4506
- syntax: "solidity",
4507
- value: "solidity"
4508
- }
4509
- ];
4510
- MODES.sort((modeA, modeB) => {
4511
- const nameA = modeA.name.toLowerCase();
4512
- const nameB = modeB.name.toLowerCase();
4513
- if (nameA === nameB) return 0;
4514
- if (nameA < nameB) return -1;
4515
- return 1;
4516
- });
4517
- MODES.unshift({
4518
- name: "Plain Text",
4519
- syntax: "simplemode",
4520
- value: "plain"
4521
- });
4522
4063
  function modeMatch(mode = "") {
4523
4064
  mode = mode.toLocaleLowerCase() || "plain";
4524
- return MODES.find((m) => m.value === mode || m.ext?.includes(mode))?.value || "plain";
4065
+ return LANGUAGES.find((m) => m.value === mode || m.ext?.includes(mode))?.value || "plain";
4525
4066
  }
4526
4067
  //#endregion
4527
4068
  //#region src/plugins/codemirror-block/plugin/index.ts
@@ -4595,419 +4136,6 @@ const CodemirrorPlugin = class extends KernelPlugin {
4595
4136
  }
4596
4137
  };
4597
4138
  //#endregion
4598
- //#region src/plugins/codemirror-block/react/theme.ts
4599
- /**
4600
- * Lobe 主题配置
4601
- * 基于 shiki 主题配置,使用 antd-style 的 cssVar 进行颜色映射
4602
- */
4603
- const lobeTheme = {
4604
- "&": {
4605
- "& .cm-cursor": { "border-left-color": cssVar.colorPrimary },
4606
- "& .cm-cursor.cm-cursor-primary": { "border-inline-start": `2px solid ${cssVar.colorPrimary} !important` },
4607
- "& .cm-gutters": {
4608
- "background-color": cssVar.colorBgContainer,
4609
- "border": "none",
4610
- "color": cssVar.colorTextQuaternary,
4611
- "cursor": "default"
4612
- },
4613
- "& .cm-line": {
4614
- "& .cm-atom": { color: cssVar.purple10 },
4615
- "& .cm-attribute": { color: cssVar.purple10 },
4616
- "& .cm-builtin": {
4617
- color: cssVar.volcano10,
4618
- fontStyle: "italic"
4619
- },
4620
- "& .cm-comment": {
4621
- color: cssVar.colorTextQuaternary,
4622
- fontStyle: "italic"
4623
- },
4624
- "& .cm-foldPlaceholder": {
4625
- "background": `url("data:image/svg+xml,%3Csvg width='16' height='16' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Crect fill='%23E8E8E8' width='16' height='16' rx='2'/%3E%3Cpath d='M2.75 7.984a.875.875 0 1 0 1.75 0 .875.875 0 0 0-1.75 0Zm4.375 0a.875.875 0 1 0 1.75 0 .875.875 0 0 0-1.75 0Zm4.375 0a.875.875 0 1 0 1.75 0 .875.875 0 0 0-1.75 0Z' fill='%232A3238'/%3E%3C/g%3E%3C/svg%3E") no-repeat`,
4626
- "border": "none",
4627
- "color": "transparent",
4628
- "display": "inline-block",
4629
- "height": "16px",
4630
- "padding": 0,
4631
- "vertical-align": "middle",
4632
- "width": "16px"
4633
- },
4634
- "& .cm-function": { color: cssVar.geekblue10 },
4635
- "& .cm-header": { color: cssVar.colorInfo },
4636
- "& .cm-keyword": { color: cssVar.colorInfo },
4637
- "& .cm-meta": { color: cssVar.colorText },
4638
- "& .cm-modifier": { color: cssVar.colorInfo },
4639
- "& .cm-number": { color: cssVar.volcano10 },
4640
- "& .cm-operator": { color: cssVar.colorInfo },
4641
- "& .cm-property": { color: cssVar.volcano10 },
4642
- "& .cm-punctuation": { color: cssVar.colorInfo },
4643
- "& .cm-qualifier": { color: cssVar.colorWarning },
4644
- "& .cm-string": { color: cssVar.colorSuccess },
4645
- "& .cm-string-2": { color: cssVar.colorSuccess },
4646
- "& .cm-tag": { color: cssVar.volcano10 },
4647
- "& .cm-tag.cm-bracket": { color: cssVar.colorInfo },
4648
- "& .cm-type": { color: cssVar.colorWarning },
4649
- "& .cm-variable": { color: cssVar.colorText },
4650
- "& .cm-variable-2": { color: cssVar.geekblue10 },
4651
- "& .cm-variable-3": { color: cssVar.colorWarning },
4652
- "& .cm-variable.cm-callee": { color: cssVar.geekblue10 },
4653
- "& .cm-variable.cm-def": { color: cssVar.colorText },
4654
- "color": cssVar.colorText,
4655
- "padding-inline": "12px"
4656
- }
4657
- },
4658
- "& .cm-selectionBackground": { background: "transparent" },
4659
- "& .cm-selectionMatch": { background: `${cssVar.colorFillSecondary} !important` },
4660
- "&.cm-editor": {
4661
- "background": "transparent",
4662
- "cursor": "text",
4663
- "padding-block": "12px",
4664
- "width": "100%"
4665
- },
4666
- "&.cm-editor span": {
4667
- "font-family": cssVar.fontFamilyCode,
4668
- "font-size": "calc(var(--lobe-markdown-font-size) * 0.8)"
4669
- },
4670
- "&.cm-editor.cm-focused .cm-selectionBackground": { background: cssVar.colorPrimaryBg },
4671
- "&.cm-editor.cm-focused .cm-selectionLineGutter": { color: cssVar.colorText },
4672
- "&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": { background: cssVar.yellow }
4673
- };
4674
- //#endregion
4675
- //#region src/plugins/codemirror-block/lib/index.ts
4676
- init_debug();
4677
- const logger$4 = createDebugLogger("plugin", "codemirror-loader");
4678
- const DEFAULT_CDN_URL = "https://registry.npmmirror.com/@lobehub/codemirror/1.0.0/files/es/index.js";
4679
- const LOAD_TIMEOUT = 1e4;
4680
- const POLL_INTERVAL = 50;
4681
- let codeMirrorPromise = null;
4682
- /**
4683
- * 加载 script 标签
4684
- */
4685
- function loadScript(src) {
4686
- return new Promise((resolve, reject) => {
4687
- if (document.querySelector(`script[src="${src}"]`)) {
4688
- logger$4.debug("Script already loaded:", src);
4689
- resolve();
4690
- return;
4691
- }
4692
- logger$4.debug("Loading script:", src);
4693
- const script = document.createElement("script");
4694
- script.src = src;
4695
- script.type = "module";
4696
- script.async = true;
4697
- script.addEventListener("load", () => {
4698
- logger$4.debug("Script loaded successfully:", src);
4699
- resolve();
4700
- });
4701
- script.addEventListener("error", (error) => {
4702
- logger$4.error("Failed to load script:", src, error);
4703
- reject(/* @__PURE__ */ new Error(`Failed to load script: ${src}`));
4704
- });
4705
- document.head.append(script);
4706
- });
4707
- }
4708
- /**
4709
- * 等待 window.CodeMirror 可用
4710
- */
4711
- function waitForCodeMirror(timeout = LOAD_TIMEOUT) {
4712
- return new Promise((resolve, reject) => {
4713
- const startTime = Date.now();
4714
- const checkCodeMirror = () => {
4715
- if (window.CodeMirror) {
4716
- logger$4.debug("CodeMirror is ready");
4717
- resolve();
4718
- return;
4719
- }
4720
- if (Date.now() - startTime > timeout) {
4721
- logger$4.error("Timeout waiting for CodeMirror");
4722
- reject(/* @__PURE__ */ new Error("Timeout: CodeMirror failed to load from CDN"));
4723
- return;
4724
- }
4725
- setTimeout(checkCodeMirror, POLL_INTERVAL);
4726
- };
4727
- checkCodeMirror();
4728
- });
4729
- }
4730
- /**
4731
- * 从 CDN 加载 CodeMirror
4732
- * @param cdnUrl - 可选的自定义 CDN URL
4733
- */
4734
- async function loadCodeMirror(cdnUrl = DEFAULT_CDN_URL) {
4735
- if (window.CodeMirror?.default) {
4736
- logger$4.debug("CodeMirror already available");
4737
- return window.CodeMirror.default;
4738
- }
4739
- if (codeMirrorPromise) {
4740
- logger$4.debug("CodeMirror loading in progress, reusing promise");
4741
- return codeMirrorPromise;
4742
- }
4743
- codeMirrorPromise = (async () => {
4744
- try {
4745
- logger$4.debug("Starting CodeMirror load from:", cdnUrl);
4746
- await loadScript(cdnUrl);
4747
- await waitForCodeMirror();
4748
- if (!window.CodeMirror?.default) throw new Error("CodeMirror loaded but not properly initialized");
4749
- logger$4.debug("CodeMirror loaded successfully");
4750
- return window.CodeMirror.default;
4751
- } catch (error) {
4752
- codeMirrorPromise = null;
4753
- logger$4.error("Failed to load CodeMirror:", error);
4754
- throw error;
4755
- }
4756
- })();
4757
- return codeMirrorPromise;
4758
- }
4759
- //#endregion
4760
- //#region src/plugins/codemirror-block/react/components/CopyButton.tsx
4761
- const CopyButton = ({ onCopy }) => {
4762
- const [copied, setCopied] = useState(false);
4763
- return /* @__PURE__ */ jsx(ActionIcon, {
4764
- active: copied,
4765
- className: "cm-hidden-actions",
4766
- icon: copied ? Check : CopyIcon,
4767
- onClick: () => {
4768
- setCopied(true);
4769
- onCopy();
4770
- setTimeout(() => setCopied(false), 1e3);
4771
- },
4772
- size: "small",
4773
- title: "Copy"
4774
- });
4775
- };
4776
- CopyButton.displayName = "CopyButton";
4777
- //#endregion
4778
- //#region src/plugins/codemirror-block/react/components/style.ts
4779
- const styles$9 = createStaticStyles(({ css }) => ({ container: css`
4780
- min-width: 160px;
4781
- ` }));
4782
- //#endregion
4783
- //#region src/plugins/codemirror-block/react/components/LanguageSelect.tsx
4784
- const LanguageSelect = ({ selectedLang, onLanguageChange }) => {
4785
- const t = useTranslation();
4786
- const languageOptions = useMemo(() => MODES.map((mode) => ({
4787
- aliases: mode.ext || [],
4788
- label: /* @__PURE__ */ jsxs(Flexbox, {
4789
- align: "center",
4790
- gap: 4,
4791
- horizontal: true,
4792
- children: [/* @__PURE__ */ jsx(MaterialFileTypeIcon, {
4793
- fallbackUnknownType: false,
4794
- filename: mode.ext?.[0] ? `*.${mode.ext[0]}` : `*.${mode.value}`,
4795
- size: 18,
4796
- type: "file",
4797
- variant: "raw"
4798
- }), /* @__PURE__ */ jsx(Text, {
4799
- ellipsis: true,
4800
- fontSize: 13,
4801
- children: mode.name
4802
- })]
4803
- }),
4804
- title: mode.ext?.length ? mode.ext.map((ext) => `*.${ext}`).join(",") : `*.${mode.value}`,
4805
- value: mode.value
4806
- })), []);
4807
- return /* @__PURE__ */ jsx(Flexbox, {
4808
- align: "center",
4809
- className: "cm-language-select",
4810
- gap: 4,
4811
- horizontal: true,
4812
- onClick: (e) => e.stopPropagation(),
4813
- children: /* @__PURE__ */ jsx(Select, {
4814
- className: cx(styles$9.container),
4815
- filterOption: (input, option) => {
4816
- const lang = input.toLowerCase();
4817
- if ((option?.value)?.toLowerCase().startsWith(lang)) return true;
4818
- if (String(option?.label).toLowerCase().includes(lang)) return true;
4819
- if (option?.aliases?.some((ext) => ext.toLowerCase().startsWith(lang))) return true;
4820
- return false;
4821
- },
4822
- onChange: onLanguageChange,
4823
- options: languageOptions,
4824
- placeholder: t("codemirror.selectLanguage"),
4825
- showSearch: true,
4826
- size: "small",
4827
- value: selectedLang,
4828
- variant: "borderless"
4829
- })
4830
- });
4831
- };
4832
- LanguageSelect.displayName = "LanguageSelect";
4833
- //#endregion
4834
- //#region src/plugins/codemirror-block/react/components/MoreOptions.tsx
4835
- const MoreOptions = ({ tabSize, onTabSizeChange, useTabs, onUseTabsChange, showLineNumbers, onShowLineNumbersChange }) => {
4836
- const t = useTranslation();
4837
- const handleTabSizeChange = useCallback((value = 2) => {
4838
- onTabSizeChange(value === null ? 2 : value);
4839
- }, [onTabSizeChange]);
4840
- return /* @__PURE__ */ jsx(Popover, {
4841
- arrow: false,
4842
- content: /* @__PURE__ */ jsxs(Flexbox, {
4843
- gap: 8,
4844
- style: { minWidth: 240 },
4845
- children: [
4846
- /* @__PURE__ */ jsxs(Flexbox, {
4847
- align: "center",
4848
- gap: 8,
4849
- horizontal: true,
4850
- justify: "space-between",
4851
- children: [/* @__PURE__ */ jsx(Text, { children: t("codemirror.tabSize") }), /* @__PURE__ */ jsx(InputNumber, {
4852
- max: 8,
4853
- min: 1,
4854
- onChange: handleTabSizeChange,
4855
- size: "small",
4856
- value: tabSize
4857
- })]
4858
- }),
4859
- /* @__PURE__ */ jsxs(Flexbox, {
4860
- align: "center",
4861
- gap: 8,
4862
- horizontal: true,
4863
- justify: "space-between",
4864
- children: [/* @__PURE__ */ jsx(Text, { children: t("codemirror.useTabs") }), /* @__PURE__ */ jsx(Switch, {
4865
- checked: useTabs,
4866
- onChange: onUseTabsChange,
4867
- size: "small"
4868
- })]
4869
- }),
4870
- /* @__PURE__ */ jsxs(Flexbox, {
4871
- align: "center",
4872
- gap: 8,
4873
- horizontal: true,
4874
- justify: "space-between",
4875
- children: [/* @__PURE__ */ jsx(Text, { children: t("codemirror.showLineNumbers") }), /* @__PURE__ */ jsx(Switch, {
4876
- checked: showLineNumbers,
4877
- onChange: onShowLineNumbersChange,
4878
- size: "small"
4879
- })]
4880
- })
4881
- ]
4882
- }),
4883
- placement: "bottomRight",
4884
- trigger: "click",
4885
- children: /* @__PURE__ */ jsx(ActionIcon, {
4886
- className: "cm-hidden-actions",
4887
- icon: MoreHorizontalIcon,
4888
- size: "small"
4889
- })
4890
- });
4891
- };
4892
- MoreOptions.displayName = "MoreOptions";
4893
- //#endregion
4894
- //#region src/plugins/codemirror-block/react/components/Toolbar.tsx
4895
- const Toolbar = ({ selectedLang, onLanguageChange, onCopy, tabSize, onTabSizeChange, useTabs, onUseTabsChange, showLineNumbers, onShowLineNumbersChange, onClick, expand, toggleExpand }) => {
4896
- return /* @__PURE__ */ jsxs(Flexbox, {
4897
- align: "center",
4898
- className: "cm-header-toolbar",
4899
- horizontal: true,
4900
- justify: "space-between",
4901
- onClick,
4902
- padding: 4,
4903
- children: [/* @__PURE__ */ jsx(LanguageSelect, {
4904
- onLanguageChange,
4905
- selectedLang
4906
- }), /* @__PURE__ */ jsxs(Flexbox, {
4907
- gap: 4,
4908
- horizontal: true,
4909
- onClick: (e) => e.stopPropagation(),
4910
- children: [
4911
- /* @__PURE__ */ jsx(MoreOptions, {
4912
- onShowLineNumbersChange,
4913
- onTabSizeChange,
4914
- onUseTabsChange,
4915
- showLineNumbers,
4916
- tabSize,
4917
- useTabs
4918
- }),
4919
- /* @__PURE__ */ jsx(CopyButton, { onCopy }),
4920
- /* @__PURE__ */ jsx(ActionIcon, {
4921
- icon: expand ? ChevronDown : ChevronRight,
4922
- onClick: toggleExpand,
4923
- size: "small"
4924
- })
4925
- ]
4926
- })]
4927
- });
4928
- };
4929
- Toolbar.displayName = "Toolbar";
4930
- //#endregion
4931
- //#region src/plugins/codemirror-block/react/style.ts
4932
- const styles$8 = createStaticStyles(({ css, cssVar }) => css`
4933
- cursor: pointer;
4934
-
4935
- position: relative;
4936
-
4937
- overflow: hidden;
4938
- display: flex;
4939
- flex-direction: column;
4940
- align-items: center;
4941
-
4942
- width: 100%;
4943
- margin-block: calc(var(--lobe-markdown-margin-multiple) * 0.5em);
4944
- border-radius: var(--lobe-markdown-border-radius);
4945
-
4946
- background: ${cssVar.colorFillQuaternary};
4947
-
4948
- .cm-hidden-actions {
4949
- opacity: 0;
4950
- transition: opacity 0.2s ease-in-out;
4951
- }
4952
-
4953
- .cm-language-select {
4954
- opacity: 0.5;
4955
- filter: grayscale(100%);
4956
- transition:
4957
- opacity,
4958
- grayscale 0.2s ease-in-out;
4959
- }
4960
-
4961
- &.selected {
4962
- user-select: none;
4963
- }
4964
-
4965
- &.selected::after {
4966
- pointer-events: none;
4967
- content: '';
4968
-
4969
- position: absolute;
4970
- z-index: 10;
4971
- inset: 0;
4972
-
4973
- width: 100%;
4974
- height: 100%;
4975
-
4976
- opacity: 0.2;
4977
- background: ${cssVar.yellow};
4978
-
4979
- transition: all 0.3s;
4980
- }
4981
-
4982
- .cm-container {
4983
- position: relative;
4984
- width: 100%;
4985
- border-block-start: 1px solid ${cssVar.colorFillQuaternary};
4986
- }
4987
-
4988
- .cm-container-collapsed {
4989
- overflow: hidden;
4990
- height: 0;
4991
- border-block-start: none;
4992
- }
4993
-
4994
- .cm-textarea {
4995
- height: 44px;
4996
- opacity: 0;
4997
- }
4998
-
4999
- &:hover {
5000
- .cm-hidden-actions {
5001
- opacity: 1;
5002
- }
5003
-
5004
- .cm-language-select {
5005
- opacity: 1;
5006
- filter: grayscale(0);
5007
- }
5008
- }
5009
- `);
5010
- //#endregion
5011
4139
  //#region src/plugins/codemirror-block/react/CodemirrorNode.tsx
5012
4140
  const ReactCodemirrorNode = ({ node, className, editor }) => {
5013
4141
  const ref = useRef(null);
@@ -5026,11 +4154,15 @@ const ReactCodemirrorNode = ({ node, className, editor }) => {
5026
4154
  const code = instanceRef.current.getValue();
5027
4155
  try {
5028
4156
  await navigator.clipboard.writeText(code);
5029
- } catch {
5030
- message.error(t("codemirror.copyFailed"));
5031
- }
4157
+ } catch {}
5032
4158
  }
5033
- }, [t]);
4159
+ }, []);
4160
+ const labels = useMemo(() => ({
4161
+ selectLanguage: t("codemirror.selectLanguage"),
4162
+ showLineNumbers: t("codemirror.showLineNumbers"),
4163
+ tabSize: t("codemirror.tabSize"),
4164
+ useTabs: t("codemirror.useTabs")
4165
+ }), [t]);
5034
4166
  const handleLanguageChange = useCallback((value) => {
5035
4167
  setSelectedLang(value);
5036
4168
  if (instanceRef.current) instanceRef.current.setOption("mode", value);
@@ -5177,13 +4309,14 @@ const ReactCodemirrorNode = ({ node, className, editor }) => {
5177
4309
  setSelected
5178
4310
  ]);
5179
4311
  return /* @__PURE__ */ jsxs(Block, {
5180
- className: cx(styles$8, isSelected && !isNodeSelected && "selected", className),
4312
+ className: cx(styles$14, isSelected && !isNodeSelected && "selected", className),
5181
4313
  onMouseDown: (e) => e.stopPropagation(),
5182
4314
  onMouseUp: (e) => e.stopPropagation(),
5183
4315
  onSelect: (e) => e.stopPropagation(),
5184
4316
  variant: "filled",
5185
4317
  children: [/* @__PURE__ */ jsx(Toolbar, {
5186
4318
  expand,
4319
+ labels,
5187
4320
  onClick: () => setExpand(!expand),
5188
4321
  onCopy: handleCopy,
5189
4322
  onLanguageChange: handleLanguageChange,
@@ -5449,11 +4582,11 @@ const ContentBlocksPlugin = class extends KernelPlugin {
5449
4582
  };
5450
4583
  //#endregion
5451
4584
  //#region src/plugins/content-blocks/utils/extract-media-lists.ts
5452
- const generateId$1 = () => {
4585
+ const generateId = () => {
5453
4586
  if (typeof globalThis.crypto?.randomUUID === "function") return globalThis.crypto.randomUUID();
5454
4587
  return `id-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`;
5455
4588
  };
5456
- const inferFileType$1 = (name) => {
4589
+ const inferFileType = (name) => {
5457
4590
  const dotIndex = name.lastIndexOf(".");
5458
4591
  if (dotIndex < 0 || dotIndex === name.length - 1) return "unknown";
5459
4592
  return name.slice(dotIndex + 1).toLowerCase() || "unknown";
@@ -5463,12 +4596,12 @@ const extractMediaLists = (blocks) => {
5463
4596
  const fileList = [];
5464
4597
  for (const block of blocks) if (block.type === "image") imageList.push({
5465
4598
  alt: block.alt,
5466
- id: generateId$1(),
4599
+ id: generateId(),
5467
4600
  url: block.url
5468
4601
  });
5469
4602
  else if (block.type === "file") fileList.push({
5470
- fileType: inferFileType$1(block.name),
5471
- id: generateId$1(),
4603
+ fileType: inferFileType(block.name),
4604
+ id: generateId(),
5472
4605
  name: block.name,
5473
4606
  size: typeof block.size === "number" ? block.size : 0,
5474
4607
  url: block.url
@@ -5766,7 +4899,7 @@ const ReactFilePlugin = ({ className, locale, handleUpload, markdownWriter, them
5766
4899
  throw new Error("No upload handler provided");
5767
4900
  },
5768
4901
  markdownWriter,
5769
- theme: theme || styles$16
4902
+ theme: theme || styles$15
5770
4903
  });
5771
4904
  }, [editor]);
5772
4905
  return null;
@@ -6730,7 +5863,7 @@ const ReactImagePlugin = ({ theme, className, defaultBlockImage, handleUpload, n
6730
5863
  onPickFile
6731
5864
  });
6732
5865
  },
6733
- theme: theme || styles$17
5866
+ theme: theme || styles$16
6734
5867
  });
6735
5868
  }, []);
6736
5869
  return null;
@@ -7339,9 +6472,9 @@ const ReactListPlugin = ({ enableHotkey = true }) => {
7339
6472
  editor.registerPlugin(MarkdownPlugin);
7340
6473
  editor.registerPlugin(ListPlugin, {
7341
6474
  enableHotkey,
7342
- theme: styles$18
6475
+ theme: styles$17
7343
6476
  });
7344
- }, [enableHotkey, styles$18]);
6477
+ }, [enableHotkey, styles$17]);
7345
6478
  return null;
7346
6479
  };
7347
6480
  ReactListPlugin.displayName = "ReactListPlugin";
@@ -7586,7 +6719,7 @@ const MathEditorContainer = memo(({ children, isBlockMode, mathDOM, onFocus, pre
7586
6719
  return /* @__PURE__ */ jsx(Popover, {
7587
6720
  arrow: false,
7588
6721
  content: /* @__PURE__ */ jsx(Flexbox, {
7589
- className: styles$19.mathEditor,
6722
+ className: styles$18.mathEditor,
7590
6723
  "data-math-editor-container": true,
7591
6724
  style: blockWidth ? { width: blockWidth } : void 0,
7592
6725
  children
@@ -7598,7 +6731,7 @@ const MathEditorContainer = memo(({ children, isBlockMode, mathDOM, onFocus, pre
7598
6731
  padding: 0
7599
6732
  } },
7600
6733
  children: /* @__PURE__ */ jsx("span", {
7601
- className: styles$19.mathEditorAnchor,
6734
+ className: styles$18.mathEditorAnchor,
7602
6735
  onClick: handleAnchorClick,
7603
6736
  ref: anchorRef
7604
6737
  })
@@ -7682,7 +6815,7 @@ const MathEditorContent = memo(({ focusRef, mathNode, onArrowLeft, onArrowRight,
7682
6815
  maxRows: 6,
7683
6816
  minRows: 1
7684
6817
  },
7685
- className: styles$19.mathEditorTextArea,
6818
+ className: styles$18.mathEditorTextArea,
7686
6819
  onChange: (e) => {
7687
6820
  onValueChange(e.target.value);
7688
6821
  },
@@ -7694,7 +6827,7 @@ const MathEditorContent = memo(({ focusRef, mathNode, onArrowLeft, onArrowRight,
7694
6827
  variant: "borderless"
7695
6828
  }),
7696
6829
  latexError && /* @__PURE__ */ jsx(Flexbox, {
7697
- className: styles$19.mathEditorFooter,
6830
+ className: styles$18.mathEditorFooter,
7698
6831
  horizontal: true,
7699
6832
  paddingBlock: 4,
7700
6833
  paddingInline: 12,
@@ -7706,7 +6839,7 @@ const MathEditorContent = memo(({ focusRef, mathNode, onArrowLeft, onArrowRight,
7706
6839
  })
7707
6840
  }),
7708
6841
  /* @__PURE__ */ jsx(Flexbox, {
7709
- className: styles$19.mathEditorFooter,
6842
+ className: styles$18.mathEditorFooter,
7710
6843
  horizontal: true,
7711
6844
  justify: "flex-end",
7712
6845
  padding: 4,
@@ -7920,7 +7053,7 @@ const Placeholder = ({ mathBlock }) => {
7920
7053
  const t = useTranslation();
7921
7054
  const node = /* @__PURE__ */ jsx(Text, {
7922
7055
  as: "span",
7923
- className: cx("katex", styles$19.mathPlaceholder),
7056
+ className: cx("katex", styles$18.mathPlaceholder),
7924
7057
  fontSize: mathBlock ? "1.2em" : "1em",
7925
7058
  type: "secondary",
7926
7059
  children: t("math.placeholder")
@@ -8021,13 +7154,13 @@ const ReactMathPlugin = ({ className, renderComp, theme }) => {
8021
7154
  node
8022
7155
  });
8023
7156
  },
8024
- theme: theme || styles$19
7157
+ theme: theme || styles$18
8025
7158
  });
8026
7159
  }, [
8027
7160
  editor,
8028
7161
  className,
8029
7162
  theme,
8030
- styles$19
7163
+ styles$18
8031
7164
  ]);
8032
7165
  return /* @__PURE__ */ jsx(MathEdit, { renderComp });
8033
7166
  };
@@ -8900,7 +8033,7 @@ const ReactTablePlugin = ({ className, locale }) => {
8900
8033
  }, []);
8901
8034
  useLayoutEffect(() => {
8902
8035
  if (locale) editor.registerLocale(locale);
8903
- editor.registerPlugin(TablePlugin, { theme: cx(styles$20, className) });
8036
+ editor.registerPlugin(TablePlugin, { theme: cx(styles$19, className) });
8904
8037
  }, []);
8905
8038
  useLexicalEditor((editor) => {
8906
8039
  setLexicalEditor(editor);
@@ -9321,54 +8454,6 @@ const ReactVirtualBlockPlugin = () => {
9321
8454
  };
9322
8455
  ReactVirtualBlockPlugin.displayName = "ReactVirtualBlockPlugin";
9323
8456
  //#endregion
9324
- //#region src/utils/extract-media-from-editor-state.ts
9325
- const IMAGE_TYPES = new Set(["image", "block-image"]);
9326
- const FILE_TYPE = "file";
9327
- const generateId = () => {
9328
- if (typeof globalThis.crypto?.randomUUID === "function") return globalThis.crypto.randomUUID();
9329
- return `id-${Math.random().toString(36).slice(2)}-${Date.now().toString(36)}`;
9330
- };
9331
- const inferFileType = (name) => {
9332
- const dotIndex = name.lastIndexOf(".");
9333
- if (dotIndex < 0 || dotIndex === name.length - 1) return "unknown";
9334
- return name.slice(dotIndex + 1).toLowerCase() || "unknown";
9335
- };
9336
- const extractMediaFromEditorState = (state) => {
9337
- const imageList = [];
9338
- const fileList = [];
9339
- const visit = (node) => {
9340
- const type = node.type;
9341
- if (IMAGE_TYPES.has(type)) {
9342
- if (node.status === "uploaded" && typeof node.src === "string" && node.src) imageList.push({
9343
- alt: typeof node.altText === "string" ? node.altText : "",
9344
- id: generateId(),
9345
- url: node.src
9346
- });
9347
- return;
9348
- }
9349
- if (type === FILE_TYPE) {
9350
- if (node.status === "uploaded" && typeof node.fileUrl === "string" && node.fileUrl) {
9351
- const name = typeof node.name === "string" ? node.name : "unknown";
9352
- fileList.push({
9353
- fileType: inferFileType(name),
9354
- id: generateId(),
9355
- name,
9356
- size: typeof node.size === "number" ? node.size : 0,
9357
- url: node.fileUrl
9358
- });
9359
- }
9360
- return;
9361
- }
9362
- if (Array.isArray(node.children)) for (const child of node.children) visit(child);
9363
- };
9364
- const root = state?.root;
9365
- if (root && Array.isArray(root.children)) for (const child of root.children) visit(child);
9366
- return {
9367
- fileList,
9368
- imageList
9369
- };
9370
- };
9371
- //#endregion
9372
8457
  //#region src/utils/scrollIntoView.ts
9373
8458
  init_kernel();
9374
8459
  /**