diff --git a/apps/web/index.html b/apps/web/index.html index 4fa39de3c..0ecbee2dc 100644 --- a/apps/web/index.html +++ b/apps/web/index.html @@ -106,6 +106,7 @@ id="MathJax-script" src="https://cdn-doocs.oss-cn-shenzhen.aliyuncs.com/npm/mathjax@3/es5/tex-svg.js" > + diff --git a/apps/web/package.json b/apps/web/package.json index 027e99e8b..385a6886e 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -42,7 +42,7 @@ "buffer-from": "^1.1.2", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", - "codemirror": "^5.65.19", + "codemirror": "^6.0.1", "core-js": "^3.45.1", "cos-js-sdk-v5": "^1.8.7", "crypto-js": "^4.2.0", @@ -83,7 +83,6 @@ "@tailwindcss/postcss": "^4.1.13", "@tailwindcss/vite": "^4.1.13", "@types/buffer-from": "^1.1.3", - "@types/codemirror": "^5.60.15", "@types/crypto-js": "^4.2.2", "@types/mdast": "^4.0.4", "@types/unist": "^3.0.3", diff --git a/apps/web/src/assets/less/app.less b/apps/web/src/assets/less/app.less index 093a01d7d..89619c268 100644 --- a/apps/web/src/assets/less/app.less +++ b/apps/web/src/assets/less/app.less @@ -47,7 +47,6 @@ section { display: block; height: 100%; width: 100%; - padding: 10px; border: none; } diff --git a/apps/web/src/assets/less/theme.less b/apps/web/src/assets/less/theme.less index 2bf6ef0f4..d925d3926 100644 --- a/apps/web/src/assets/less/theme.less +++ b/apps/web/src/assets/less/theme.less @@ -8,6 +8,8 @@ .dark { .container { + // CodeMirror v6 兼容 + .cm-editor, .CodeMirror-wrap { background-color: @nightCodeMirrorColor; } @@ -34,6 +36,7 @@ } } +// CodeMirror v5 兼容样式 .CodeMirror { padding-bottom: 0; height: 100% !important; @@ -51,12 +54,6 @@ overflow-y: scroll !important; } -.cssEditor-wrapper { - .CodeMirror-scroll { - margin-right: 0; - } -} - .CodeMirror-vscrollbar { width: 0px; height: 0px; @@ -68,6 +65,42 @@ box-sizing: border-box; } +// CodeMirror v6 样式 +.cm-editor { + height: 100% !important; + font-size: 16px; + font-family: Consolas, 'Courier New', monospace !important; + + .cm-scroller { + overflow-x: hidden !important; + overflow-y: auto !important; + } + + .cm-content { + padding-bottom: 20px; + } + + &.cm-focused { + outline: none; + } +} + +.codemirror-container { + height: 100%; + width: 100%; + + .cm-scroller { + padding: 10px; + } +} + +.cssEditor-wrapper { + .CodeMirror-scroll, + .cm-scroller { + margin-right: 0; + } +} + .cm-em { font-style: normal; } diff --git a/apps/web/src/components/ai/SidebarAIToolbar.vue b/apps/web/src/components/ai/SidebarAIToolbar.vue index e492f3fe4..c55592b82 100644 --- a/apps/web/src/components/ai/SidebarAIToolbar.vue +++ b/apps/web/src/components/ai/SidebarAIToolbar.vue @@ -26,7 +26,10 @@ const toolBoxVisible = ref(false) // 检查选中文本的函数 function getSelectedText() { try { - return editor.value?.getSelection()?.trim() || `` + if (!editor.value) + return `` + const selection = editor.value.state.selection.main + return editor.value.state.doc.sliceString(selection.from, selection.to).trim() } catch { return `` diff --git a/apps/web/src/components/ai/chat-box/AIAssistantPanel.vue b/apps/web/src/components/ai/chat-box/AIAssistantPanel.vue index 0b6540728..4958b9fab 100644 --- a/apps/web/src/components/ai/chat-box/AIAssistantPanel.vue +++ b/apps/web/src/components/ai/chat-box/AIAssistantPanel.vue @@ -284,7 +284,7 @@ async function sendMessage() { ? [{ role: `system`, content: - `下面是一篇 Markdown 文章全文,请严格以此为主完成后续指令:\n\n${editor.value!.getValue()}`, + `下面是一篇 Markdown 文章全文,请严格以此为主完成后续指令:\n\n${editor.value?.state.doc.toString()}`, }] : [] diff --git a/apps/web/src/components/ai/image-generator/AIImageGeneratorPanel.vue b/apps/web/src/components/ai/image-generator/AIImageGeneratorPanel.vue index fa7a97a38..21ea66e71 100644 --- a/apps/web/src/components/ai/image-generator/AIImageGeneratorPanel.vue +++ b/apps/web/src/components/ai/image-generator/AIImageGeneratorPanel.vue @@ -504,12 +504,11 @@ function insertImageToCursor(imageUrl: string) { const markdownImage = `![${altText}](${imageUrl})` // 获取当前光标位置并插入 - const cursor = editor.value.getCursor() - editor.value.replaceRange(markdownImage, cursor) - - // 将光标移动到插入内容后面 - const newCursor = { line: cursor.line, ch: cursor.ch + markdownImage.length } - editor.value.setCursor(newCursor) + const pos = editor.value.state.selection.main.head + editor.value.dispatch({ + changes: { from: pos, insert: markdownImage }, + selection: { anchor: pos + markdownImage.length }, + }) // 聚焦编辑器 editor.value.focus() diff --git a/apps/web/src/components/ai/tool-box/ToolBoxPopover.vue b/apps/web/src/components/ai/tool-box/ToolBoxPopover.vue index 62bd3ee18..4ae356a92 100644 --- a/apps/web/src/components/ai/tool-box/ToolBoxPopover.vue +++ b/apps/web/src/components/ai/tool-box/ToolBoxPopover.vue @@ -251,12 +251,16 @@ function stopAI() { /* -------------------- actions -------------------- */ function replaceText() { - const cm = toRaw(store.editor!)! - const start = cm.getCursor(`start`) - cm.replaceSelection(message.value) - const end = cm.getCursor(`end`) - cm.setSelection(start, end) - cm.focus() + const editorView = toRaw(store.editor!)! + const selection = editorView.state.selection.main + editorView.dispatch(editorView.state.replaceSelection(message.value)) + + // 选中替换后的文本 + const newSelection = editorView.state.selection.main + editorView.dispatch({ + selection: { anchor: selection.from, head: newSelection.head }, + }) + editorView.focus() currentText.value = message.value resetState() diff --git a/apps/web/src/components/ai/tool-box/index.ts b/apps/web/src/components/ai/tool-box/index.ts index eab579d88..c7b694b66 100644 --- a/apps/web/src/components/ai/tool-box/index.ts +++ b/apps/web/src/components/ai/tool-box/index.ts @@ -1,4 +1,4 @@ -import type { Editor } from 'codemirror' +import type { EditorView } from '@codemirror/view' import AIPolishButton from './ToolBoxButton.vue' import AIPolishPopover from './ToolBoxPopover.vue' @@ -10,9 +10,12 @@ function useAIPolish() { const selectedText = ref(``) // 获取当前编辑器选中文本的简单函数 - function getCurrentSelection(editor: Editor | null): string { + function getCurrentSelection(editor: EditorView | null): string { try { - return editor?.getSelection()?.trim() || `` + if (!editor) + return `` + const selection = editor.state.selection.main + return editor.state.doc.sliceString(selection.from, selection.to).trim() } catch { return `` diff --git a/apps/web/src/components/editor/CssEditor.vue b/apps/web/src/components/editor/CssEditor.vue index ff4037e08..3e38dd127 100644 --- a/apps/web/src/components/editor/CssEditor.vue +++ b/apps/web/src/components/editor/CssEditor.vue @@ -129,7 +129,7 @@ function tabChanged(tabName: string | number) {
-
-