@@ -2,39 +2,51 @@ import type * as MonacoTypes from 'monaco-editor'
2
2
import { XMLValidator } from 'fast-xml-parser'
3
3
4
4
export function setupXMLValidation ( monaco : typeof MonacoTypes ) {
5
- const xmlModels = new Set < MonacoTypes . editor . ITextModel > ( )
5
+ const markerId = 'xml-validation'
6
+ const contentChangeListeners = new Map < MonacoTypes . editor . ITextModel , MonacoTypes . IDisposable > ( )
6
7
7
8
monaco . editor . onWillDisposeModel ( model => {
8
- xmlModels . delete ( model )
9
+ contentChangeListeners . delete ( model )
9
10
} )
10
11
11
- monaco . editor . onDidChangeModelLanguage ( event => {
12
- const model = event . model
13
- if ( model . getModeId ( ) === 'xml' && ! xmlModels . has ( model ) ) {
14
- xmlModels . add ( model )
15
- model . onDidChangeContent ( ( ) => {
16
- const markers : MonacoTypes . editor . IMarkerData [ ] = [ ]
17
- const text = model . getValue ( )
18
-
19
- if ( text . trim ( ) ) {
20
- const validationResult = XMLValidator . validate ( text , {
21
- allowBooleanAttributes : true ,
22
- } )
23
-
24
- if ( validationResult !== true ) {
25
- markers . push ( {
26
- severity : monaco . MarkerSeverity . Error ,
27
- startLineNumber : validationResult . err . line ,
28
- startColumn : validationResult . err . col ,
29
- endLineNumber : validationResult . err . line ,
30
- endColumn : validationResult . err . col + 10 , // the 10 is totally arbitrary here
31
- message : validationResult . err . msg ,
32
- } )
33
- }
34
- }
35
-
36
- monaco . editor . setModelMarkers ( model , 'xml-validation' , markers )
12
+ function validate ( model : MonacoTypes . editor . ITextModel ) {
13
+ const markers : MonacoTypes . editor . IMarkerData [ ] = [ ]
14
+ const text = model . getValue ( )
15
+
16
+ if ( text . trim ( ) ) {
17
+ const validationResult = XMLValidator . validate ( text , {
18
+ allowBooleanAttributes : true ,
37
19
} )
20
+
21
+ if ( validationResult !== true ) {
22
+ markers . push ( {
23
+ severity : monaco . MarkerSeverity . Error ,
24
+ startLineNumber : validationResult . err . line ,
25
+ startColumn : validationResult . err . col ,
26
+ endLineNumber : validationResult . err . line ,
27
+ endColumn : model . getLineContent ( validationResult . err . line ) . length + 1 ,
28
+ message : validationResult . err . msg ,
29
+ } )
30
+ }
31
+ }
32
+
33
+ monaco . editor . setModelMarkers ( model , markerId , markers )
34
+ }
35
+
36
+ monaco . editor . onDidChangeModelLanguage ( ( { model } ) => {
37
+ const isXml = model . getModeId ( ) === 'xml'
38
+ const listener = contentChangeListeners . get ( model )
39
+
40
+ if ( isXml && ! listener ) {
41
+ contentChangeListeners . set (
42
+ model ,
43
+ model . onDidChangeContent ( ( ) => validate ( model ) )
44
+ )
45
+ validate ( model )
46
+ } else if ( ! isXml && listener ) {
47
+ listener . dispose ( )
48
+ contentChangeListeners . delete ( model )
49
+ monaco . editor . setModelMarkers ( model , markerId , [ ] )
38
50
}
39
51
} )
40
52
}
0 commit comments