@@ -27,15 +27,7 @@ export class CodeBlockView implements NodeView {
27
27
) {
28
28
this . dom = document . createElement ( "div" ) ;
29
29
this . dom . classList . add ( "ps-relative" , "p0" , "ws-normal" , "ow-normal" ) ;
30
-
31
- const rawLanguage = this . getLanguageFromBlock ( node ) ;
32
- this . language = rawLanguage ;
33
-
34
- this . dom . innerHTML = escapeHTML `
35
- < div class ="ps-absolute t2 r4 fs-fine pe-none us-none fc-black-300 js-language-indicator " contenteditable =false > ${ rawLanguage } </ div >
36
- < pre class ="s-code-block "> < code class ="content-dom "> </ code > </ pre >
37
- ` ;
38
-
30
+ this . render ( view , getPos ) ;
39
31
this . contentDOM = this . dom . querySelector ( ".content-dom" ) ;
40
32
this . update ( node ) ;
41
33
}
@@ -49,7 +41,7 @@ export class CodeBlockView implements NodeView {
49
41
const rawLanguage = this . getLanguageFromBlock ( node ) ;
50
42
51
43
const processorApplies = this . getValidProcessorResult (
52
- rawLanguage ,
44
+ rawLanguage . raw ,
53
45
node
54
46
) ;
55
47
@@ -68,7 +60,6 @@ export class CodeBlockView implements NodeView {
68
60
const randomId = generateRandomId ( ) ;
69
61
70
62
this . dom . innerHTML = escapeHTML `
71
- < div class ="ps-absolute t2 r4 fs-fine pe-none us-none fc-black-300 js-language-indicator " contenteditable =false > </ div >
72
63
< div class ="d-flex ps-absolute t0 r0 js-processor-toggle ">
73
64
< label class ="flex--item mr4 " for ="js-editor-toggle- ${ randomId } ">
74
65
Edit
@@ -79,7 +70,8 @@ export class CodeBlockView implements NodeView {
79
70
</ div >
80
71
</ div >
81
72
< div class ="d-none js-processor-view "> </ div >
82
- < pre class ="s-code-block js-code-view js-code-mode "> < code class ="content-dom "> </ code > </ pre > ` ;
73
+ < pre class ="s-code-block js-code-view js-code-mode "> < code class ="content-dom "> </ code > </ pre >
74
+ < div class ="s-select s-select__sm ps-absolute t6 r6 js-language-indicator "> < select class ="js-lang-select "> </ select > </ div > ` ;
83
75
84
76
this . contentDOM = this . dom . querySelector ( ".content-dom" ) ;
85
77
@@ -102,6 +94,8 @@ export class CodeBlockView implements NodeView {
102
94
} )
103
95
) ;
104
96
} ) ;
97
+
98
+ this . initializeLanguageSelect ( view , getPos ) ;
105
99
}
106
100
107
101
/** Switches the view between editor mode and processor mode */
@@ -116,61 +110,6 @@ export class CodeBlockView implements NodeView {
116
110
}
117
111
118
112
/** Gets the codeblock language from the node */
119
- private getLanguageFromBlock ( node : ProsemirrorNode ) {
120
- let autodetectedLanguage = node . attrs
121
- . detectedHighlightLanguage as string ;
122
-
123
- // add an "auto" dropdown that we can target via JS
124
- const autoOpt = document . createElement ( "option" ) ;
125
- autoOpt . textContent = "auto" ;
126
- autoOpt . value = "auto" ;
127
- autoOpt . className = "js-auto-option" ;
128
- $sel . appendChild ( autoOpt ) ;
129
-
130
- getLoadedLanguages ( ) . forEach ( ( lang ) => {
131
- const opt = document . createElement ( "option" ) ;
132
- opt . value = lang ;
133
- opt . textContent = lang ;
134
- opt . defaultSelected = lang === this . language . raw ;
135
- $sel . appendChild ( opt ) ;
136
- } ) ;
137
-
138
- if ( typeof getPos !== "function" ) {
139
- return ;
140
- }
141
-
142
- // when the dropdown is changed, update the language on the node
143
- $sel . addEventListener ( "change" , ( e ) => {
144
- e . stopPropagation ( ) ;
145
-
146
- const newLang = $sel . value ;
147
-
148
- view . dispatch (
149
- view . state . tr . setNodeMarkup ( getPos ( ) , null , {
150
- params : newLang === "auto" ? null : newLang ,
151
- detectedHighlightLanguage : null ,
152
- } )
153
- ) ;
154
- } ) ;
155
- }
156
-
157
- private updateDisplayedLanguage ( ) {
158
- const lang = this . language . raw ;
159
- const $sel =
160
- this . dom . querySelector < HTMLSelectElement > ( ".js-lang-select" ) ;
161
- const $auto = $sel . querySelector ( ".js-auto-option" ) ;
162
-
163
- if ( this . language . autodetected ) {
164
- $sel . value = "auto" ;
165
- $auto . textContent = _t ( "nodes.codeblock_lang_auto" , {
166
- lang,
167
- } ) ;
168
- } else {
169
- $sel . value = lang ;
170
- $auto . textContent = _t ( "nodes.codeblock_auto" ) ;
171
- }
172
- }
173
-
174
113
private getLanguageFromBlock ( node : ProsemirrorNode ) {
175
114
const autodetectedLanguage = node . attrs
176
115
. detectedHighlightLanguage as string ;
@@ -182,11 +121,13 @@ export class CodeBlockView implements NodeView {
182
121
}
183
122
184
123
/** Updates the edit/code view */
185
- private updateCodeBlock ( rawLanguage : string ) {
186
- if ( this . language !== rawLanguage ) {
187
- this . dom . querySelector ( ".js-language-indicator" ) . textContent =
188
- rawLanguage ;
124
+ private updateCodeBlock ( rawLanguage : CodeBlockView [ "language" ] ) {
125
+ if ( this . language ?. raw !== rawLanguage . raw ) {
126
+ this . dom . querySelector < HTMLSelectElement > (
127
+ ".js-language-indicator"
128
+ ) . value = rawLanguage . raw ;
189
129
this . language = rawLanguage ;
130
+ this . updateDisplayedLanguage ( ) ;
190
131
}
191
132
}
192
133
@@ -245,4 +186,59 @@ export class CodeBlockView implements NodeView {
245
186
246
187
return processors ;
247
188
}
189
+
190
+ private initializeLanguageSelect ( view : EditorView , getPos : getPosParam ) {
191
+ const $sel =
192
+ this . dom . querySelector < HTMLSelectElement > ( ".js-lang-select" ) ;
193
+
194
+ // add an "auto" dropdown that we can target via JS
195
+ const autoOpt = document . createElement ( "option" ) ;
196
+ autoOpt . textContent = "auto" ;
197
+ autoOpt . value = "auto" ;
198
+ autoOpt . className = "js-auto-option" ;
199
+ $sel . appendChild ( autoOpt ) ;
200
+
201
+ getLoadedLanguages ( ) . forEach ( ( lang ) => {
202
+ const opt = document . createElement ( "option" ) ;
203
+ opt . value = lang ;
204
+ opt . textContent = lang ;
205
+ opt . defaultSelected = lang === this . language ?. raw ;
206
+ $sel . appendChild ( opt ) ;
207
+ } ) ;
208
+
209
+ if ( typeof getPos !== "function" ) {
210
+ return ;
211
+ }
212
+
213
+ // when the dropdown is changed, update the language on the node
214
+ $sel . addEventListener ( "change" , ( e ) => {
215
+ e . stopPropagation ( ) ;
216
+
217
+ const newLang = $sel . value ;
218
+
219
+ view . dispatch (
220
+ view . state . tr . setNodeMarkup ( getPos ( ) , null , {
221
+ params : newLang === "auto" ? null : newLang ,
222
+ detectedHighlightLanguage : null ,
223
+ } )
224
+ ) ;
225
+ } ) ;
226
+ }
227
+
228
+ private updateDisplayedLanguage ( ) {
229
+ const lang = this . language ?. raw ;
230
+ const $sel =
231
+ this . dom . querySelector < HTMLSelectElement > ( ".js-lang-select" ) ;
232
+ const $auto = $sel . querySelector ( ".js-auto-option" ) ;
233
+
234
+ if ( this . language ?. autodetected ) {
235
+ $sel . value = "auto" ;
236
+ $auto . textContent = _t ( "nodes.codeblock_lang_auto" , {
237
+ lang,
238
+ } ) ;
239
+ } else {
240
+ $sel . value = lang ;
241
+ $auto . textContent = _t ( "nodes.codeblock_auto" ) ;
242
+ }
243
+ }
248
244
}
0 commit comments