@@ -26,12 +26,11 @@ function getLanguage(filename) {
26
26
return languagesByFilename [ filename ] || languagesByExt [ extname ( filename ) ] || 'plaintext' ;
27
27
}
28
28
29
- function updateEditor ( monaco , editor , filenameInput ) {
30
- const newFilename = filenameInput . value ;
31
- editor . updateOptions ( getOptions ( filenameInput ) ) ;
29
+ function updateEditor ( monaco , editor , filename , lineWrapExts ) {
30
+ editor . updateOptions ( { ...getFileBasedOptions ( filename , lineWrapExts ) } ) ;
32
31
const model = editor . getModel ( ) ;
33
32
const language = model . getModeId ( ) ;
34
- const newLanguage = getLanguage ( newFilename ) ;
33
+ const newLanguage = getLanguage ( filename ) ;
35
34
if ( language !== newLanguage ) monaco . editor . setModelLanguage ( model , newLanguage ) ;
36
35
}
37
36
@@ -41,33 +40,22 @@ function exportEditor(editor) {
41
40
if ( ! window . codeEditors . includes ( editor ) ) window . codeEditors . push ( editor ) ;
42
41
}
43
42
44
- export async function createCodeEditor ( textarea , filenameInput , previewFileModes ) {
45
- const filename = basename ( filenameInput . value ) ;
46
- const previewLink = document . querySelector ( 'a[data-tab=preview]' ) ;
47
- const markdownExts = ( textarea . dataset . markdownFileExts || '' ) . split ( ',' ) ;
48
- const lineWrapExts = ( textarea . dataset . lineWrapExtensions || '' ) . split ( ',' ) ;
49
- const isMarkdown = markdownExts . includes ( extname ( filename ) ) ;
50
-
51
- if ( previewLink ) {
52
- if ( isMarkdown && ( previewFileModes || [ ] ) . includes ( 'markdown' ) ) {
53
- previewLink . dataset . url = previewLink . dataset . url . replace ( / ( .* ) \/ .* / i, `$1/markdown` ) ;
54
- previewLink . style . display = '' ;
55
- } else {
56
- previewLink . style . display = 'none' ;
57
- }
58
- }
59
-
43
+ export async function createMonaco ( textarea , filename , editorOpts ) {
60
44
const monaco = await import ( /* webpackChunkName: "monaco" */ 'monaco-editor' ) ;
45
+
61
46
initLanguages ( monaco ) ;
47
+ let { language, ...other } = editorOpts ;
48
+ if ( ! language ) language = getLanguage ( filename ) ;
62
49
63
50
const container = document . createElement ( 'div' ) ;
64
51
container . className = 'monaco-editor-container' ;
65
52
textarea . parentNode . appendChild ( container ) ;
66
53
67
54
const editor = monaco . editor . create ( container , {
68
55
value : textarea . value ,
69
- language : getLanguage ( filename ) ,
70
- ...getOptions ( filenameInput , lineWrapExts ) ,
56
+ theme : isDarkTheme ( ) ? 'vs-dark' : 'vs' ,
57
+ language,
58
+ ...other ,
71
59
} ) ;
72
60
73
61
const model = editor . getModel ( ) ;
@@ -80,33 +68,60 @@ export async function createCodeEditor(textarea, filenameInput, previewFileModes
80
68
editor . layout ( ) ;
81
69
} ) ;
82
70
83
- filenameInput . addEventListener ( 'keyup' , ( ) => {
84
- updateEditor ( monaco , editor , filenameInput ) ;
85
- } ) ;
71
+ exportEditor ( editor ) ;
86
72
87
73
const loading = document . querySelector ( '.editor-loading' ) ;
88
74
if ( loading ) loading . remove ( ) ;
89
75
90
- exportEditor ( editor ) ;
76
+ return { monaco, editor} ;
77
+ }
91
78
92
- return editor ;
79
+ function getFileBasedOptions ( filename , lineWrapExts ) {
80
+ return {
81
+ wordWrap : ( lineWrapExts || [ ] ) . includes ( extname ( filename ) ) ? 'on' : 'off' ,
82
+ } ;
93
83
}
94
84
95
- function getOptions ( filenameInput , lineWrapExts ) {
96
- const ec = getEditorconfig ( filenameInput ) ;
97
- const theme = isDarkTheme ( ) ? 'vs-dark' : 'vs' ;
98
- const wordWrap = ( lineWrapExts || [ ] ) . includes ( extname ( filenameInput . value ) ) ? 'on' : 'off' ;
99
-
100
- const opts = { theme, wordWrap} ;
101
- if ( isObject ( ec ) ) {
102
- opts . detectIndentation = ! ( 'indent_style' in ec ) || ! ( 'indent_size' in ec ) ;
103
- if ( 'indent_size' in ec ) opts . indentSize = Number ( ec . indent_size ) ;
104
- if ( 'tab_width' in ec ) opts . tabSize = Number ( ec . tab_width ) || opts . indentSize ;
105
- if ( 'max_line_length' in ec ) opts . rulers = [ Number ( ec . max_line_length ) ] ;
106
- opts . trimAutoWhitespace = ec . trim_trailing_whitespace === true ;
107
- opts . insertSpaces = ec . indent_style === 'space' ;
108
- opts . useTabStops = ec . indent_style === 'tab' ;
85
+ export async function createCodeEditor ( textarea , filenameInput , previewFileModes ) {
86
+ const filename = basename ( filenameInput . value ) ;
87
+ const previewLink = document . querySelector ( 'a[data-tab=preview]' ) ;
88
+ const markdownExts = ( textarea . dataset . markdownFileExts || '' ) . split ( ',' ) ;
89
+ const lineWrapExts = ( textarea . dataset . lineWrapExtensions || '' ) . split ( ',' ) ;
90
+ const isMarkdown = markdownExts . includes ( extname ( filename ) ) ;
91
+ const editorConfig = getEditorconfig ( filenameInput ) ;
92
+
93
+ if ( previewLink ) {
94
+ if ( isMarkdown && ( previewFileModes || [ ] ) . includes ( 'markdown' ) ) {
95
+ previewLink . dataset . url = previewLink . dataset . url . replace ( / ( .* ) \/ .* / i, `$1/markdown` ) ;
96
+ previewLink . style . display = '' ;
97
+ } else {
98
+ previewLink . style . display = 'none' ;
99
+ }
109
100
}
110
101
102
+ const { monaco, editor} = await createMonaco ( textarea , filename , {
103
+ ...getFileBasedOptions ( filenameInput . value , lineWrapExts ) ,
104
+ ...getEditorConfigOptions ( editorConfig ) ,
105
+ } ) ;
106
+
107
+ filenameInput . addEventListener ( 'keyup' , ( ) => {
108
+ const filename = filenameInput . value ;
109
+ updateEditor ( monaco , editor , filename , lineWrapExts ) ;
110
+ } ) ;
111
+
112
+ return editor ;
113
+ }
114
+
115
+ function getEditorConfigOptions ( ec ) {
116
+ if ( ! isObject ( ec ) ) return { } ;
117
+
118
+ const opts = { } ;
119
+ opts . detectIndentation = ! ( 'indent_style' in ec ) || ! ( 'indent_size' in ec ) ;
120
+ if ( 'indent_size' in ec ) opts . indentSize = Number ( ec . indent_size ) ;
121
+ if ( 'tab_width' in ec ) opts . tabSize = Number ( ec . tab_width ) || opts . indentSize ;
122
+ if ( 'max_line_length' in ec ) opts . rulers = [ Number ( ec . max_line_length ) ] ;
123
+ opts . trimAutoWhitespace = ec . trim_trailing_whitespace === true ;
124
+ opts . insertSpaces = ec . indent_style === 'space' ;
125
+ opts . useTabStops = ec . indent_style === 'tab' ;
111
126
return opts ;
112
127
}
0 commit comments