1
+ import type { MonacoEditor } from '@md/shared'
2
+ import type CodeMirror from 'codemirror'
1
3
import { initRenderer } from '@md/core'
4
+ import { monaco } from '@md/shared'
2
5
import {
3
6
defaultStyleConfig ,
4
7
themeMap ,
5
8
widthOptions ,
6
9
} from '@md/shared/configs'
7
- import CodeMirror from 'codemirror'
8
10
import { toPng } from 'html-to-image'
9
11
import { v4 as uuid } from 'uuid'
10
12
import DEFAULT_CONTENT from '@/assets/example/markdown.md?raw'
11
-
12
13
import DEFAULT_CSS_CONTENT from '@/assets/example/theme-css.txt?raw'
13
- import { altKey , shiftKey } from '@/configs/shortcut-key'
14
14
import {
15
15
addPrefix ,
16
16
css2json ,
@@ -28,6 +28,7 @@ import {
28
28
sanitizeTitle ,
29
29
} from '@/utils'
30
30
import { copyPlain } from '@/utils/clipboard'
31
+ import 'monaco-editor/esm/vs/basic-languages/css/css.contribution'
31
32
32
33
/**********************************
33
34
* Post 结构接口
@@ -280,10 +281,12 @@ export const useStore = defineStore(`store`, () => {
280
281
}
281
282
}
282
283
283
- // 自义定 CSS 编辑器
284
- const cssEditor = ref < CodeMirror . EditorFromTextArea | null > ( null )
284
+ // 自义定 CSS 编辑器 (Monaco Editor)
285
+ const cssEditor = ref < MonacoEditor . IStandaloneCodeEditor | null > ( null )
285
286
const setCssEditorValue = ( content : string ) => {
286
- cssEditor . value ! . setValue ( content )
287
+ if ( cssEditor . value ) {
288
+ toRaw ( cssEditor . value ) . setValue ( content )
289
+ }
287
290
}
288
291
/**
289
292
* 自定义 CSS 内容
@@ -381,7 +384,7 @@ export const useStore = defineStore(`store`, () => {
381
384
isShowLineNumber : isShowLineNumber . value ,
382
385
} )
383
386
384
- const raw = editor . value ! . getValue ( )
387
+ const raw = toRaw ( editor . value ! ) . getValue ( )
385
388
const { html : baseHtml , readingTime : readingTimeResult } = renderMarkdown ( raw , renderer )
386
389
readingTime . chars = raw . length
387
390
readingTime . words = readingTimeResult . words
@@ -409,7 +412,7 @@ export const useStore = defineStore(`store`, () => {
409
412
410
413
// 更新 CSS
411
414
const updateCss = ( ) => {
412
- const json = css2json ( cssEditor . value ! . getValue ( ) )
415
+ const json = css2json ( toRaw ( cssEditor . value ! ) . getValue ( ) )
413
416
const newTheme = customCssWithTemplate (
414
417
json ,
415
418
primaryColor . value ,
@@ -429,47 +432,40 @@ export const useStore = defineStore(`store`, () => {
429
432
const cssEditorDom = document . querySelector < HTMLTextAreaElement > (
430
433
`#cssEditor` ,
431
434
) !
432
- cssEditorDom . value = getCurrentTab ( ) . content
433
- const theme = isDark . value ? `darcula` : `xq-light`
434
- cssEditor . value = markRaw (
435
- CodeMirror . fromTextArea ( cssEditorDom , {
436
- mode : `css` ,
437
- theme,
438
- lineNumbers : false ,
439
- lineWrapping : true ,
440
- styleActiveLine : true ,
441
- matchBrackets : true ,
442
- autofocus : true ,
443
- extraKeys : {
444
- [ `${ shiftKey } -${ altKey } -F` ] : function autoFormat (
445
- editor : CodeMirror . Editor ,
446
- ) {
447
- formatDoc ( editor . getValue ( ) , `css` ) . then ( ( doc ) => {
448
- getCurrentTab ( ) . content = doc
449
- editor . setValue ( doc )
450
- } )
451
- } ,
452
- } ,
453
- } as never ) ,
454
- )
455
435
456
- // 自动提示
457
- cssEditor . value . on ( `keyup` , ( cm , e ) => {
458
- if ( ( e . keyCode >= 65 && e . keyCode <= 90 ) || e . keyCode === 189 ) {
459
- ( cm as any ) . showHint ( e )
460
- }
436
+ cssEditor . value = monaco . editor . create ( cssEditorDom , {
437
+ value : getCurrentTab ( ) . content ,
438
+ language : `css` ,
439
+ theme : isDark . value ? `vs-dark` : `vs` ,
440
+ lineNumbers : `off` ,
441
+ automaticLayout : true ,
442
+ fontSize : 14 ,
443
+ lineHeight : 22 ,
444
+ tabSize : 2 ,
445
+ minimap : { enabled : false } ,
461
446
} )
462
447
463
- // 实时保存
464
- cssEditor . value . on ( `update` , ( ) => {
465
- updateCss ( )
466
- getCurrentTab ( ) . content = cssEditor . value ! . getValue ( )
448
+ // 格式化
449
+ cssEditor . value . addCommand ( monaco . KeyMod . Alt | monaco . KeyMod . Shift | monaco . KeyCode . KeyF , ( ) => {
450
+ formatDoc ( toRaw ( cssEditor . value ! ) . getValue ( ) , `css` ) . then ( ( doc ) => {
451
+ toRaw ( cssEditor . value ! ) . setValue ( doc )
452
+ } )
453
+ } )
454
+
455
+ // 监听内容变化
456
+ cssEditor . value . onDidChangeModelContent ( ( ) => {
457
+ if ( cssEditor . value ) {
458
+ const content = toRaw ( cssEditor . value ) . getValue ( )
459
+ getCurrentTab ( ) . content = content
460
+ updateCss ( )
461
+ }
467
462
} )
468
463
} )
469
464
470
465
watch ( isDark , ( ) => {
471
- const theme = isDark . value ? `darcula` : `xq-light`
472
- toRaw ( cssEditor . value ) ?. setOption ?.( `theme` , theme )
466
+ if ( cssEditor . value ) {
467
+ cssEditor . value . updateOptions ( { theme : isDark . value ? `vs-dark` : `vs` } )
468
+ }
473
469
} )
474
470
475
471
// 重置样式
@@ -498,7 +494,9 @@ export const useStore = defineStore(`store`, () => {
498
494
] ,
499
495
}
500
496
501
- cssEditor . value ! . setValue ( DEFAULT_CSS_CONTENT )
497
+ if ( cssEditor . value ) {
498
+ toRaw ( cssEditor . value ) . setValue ( DEFAULT_CSS_CONTENT )
499
+ }
502
500
503
501
updateCss ( )
504
502
editorRefresh ( )
0 commit comments