@@ -12,6 +12,56 @@ const dictionaryDownloadUrls = {
12
12
}
13
13
}
14
14
15
+ const typoMap = new Map ( )
16
+
17
+ function createTypo ( lang , affData , dicData ) {
18
+ const typo = new Typo ( lang , affData , dicData , { platform : 'any' } )
19
+ typoMap . set ( lang , typo )
20
+ return typo
21
+ }
22
+
23
+ function request ( url ) {
24
+ return new Promise ( resolve => {
25
+ const req = new XMLHttpRequest ( )
26
+ req . open ( 'GET' , url , true )
27
+ req . onload = ( ) => {
28
+ if ( req . readyState === 4 && req . status === 200 ) {
29
+ resolve ( req . responseText )
30
+ }
31
+ }
32
+ req . send ( null )
33
+ } )
34
+ }
35
+
36
+ async function runSeriesP ( iterables , fn ) {
37
+ const results = [ ]
38
+ for ( const iterable of iterables ) {
39
+ results . push ( await fn ( iterable ) )
40
+ }
41
+ return results
42
+ }
43
+
44
+ function mapSeriesP ( iterables , fn ) {
45
+ return new Promise ( resolve => {
46
+ resolve ( runSeriesP ( iterables , fn ) )
47
+ } )
48
+ }
49
+
50
+ async function findOrCreateTypoInstance ( lang ) {
51
+ // find existing typo instance
52
+ const typo = typoMap . get ( lang )
53
+ if ( typo ) {
54
+ return typo
55
+ }
56
+
57
+ const [ affData , dicData ] = await mapSeriesP ( [
58
+ dictionaryDownloadUrls [ lang ] . aff ,
59
+ dictionaryDownloadUrls [ lang ] . dic
60
+ ] , request )
61
+
62
+ return createTypo ( lang , affData , dicData )
63
+ }
64
+
15
65
class CodeMirrorSpellChecker {
16
66
/**
17
67
* @param {CodeMirror } cm
@@ -26,53 +76,14 @@ class CodeMirrorSpellChecker {
26
76
return
27
77
}
28
78
29
- this . numLoaded = 0
30
- this . affLoading = false
31
- this . dicLoading = false
32
- this . affData = ''
33
- this . dicData = ''
34
79
this . typo = undefined
35
-
36
- this . setupCM . bind ( this ) ( cm , lang )
80
+ this . setupCM ( cm , lang )
37
81
}
38
82
39
83
setupCM ( cm , lang ) {
40
84
cm . defineMode ( 'spell-checker' , config => {
41
- // Load AFF/DIC data
42
- if ( ! this . affLoading ) {
43
- this . affLoading = true
44
-
45
- const xhrAff = new XMLHttpRequest ( )
46
- xhrAff . open ( 'GET' , dictionaryDownloadUrls [ lang ] . aff , true )
47
- xhrAff . onload = ( ) => {
48
- if ( xhrAff . readyState === 4 && xhrAff . status === 200 ) {
49
- this . affData = xhrAff . responseText
50
- this . numLoaded ++
51
-
52
- if ( this . numLoaded === 2 ) {
53
- this . typo = new Typo ( lang , this . affData , this . dicData , { platform : 'any' } )
54
- }
55
- }
56
- }
57
- xhrAff . send ( null )
58
- }
59
-
60
- if ( ! this . dicLoading ) {
61
- this . dicLoading = true
62
- const xhrDic = new XMLHttpRequest ( )
63
- xhrDic . open ( 'GET' , dictionaryDownloadUrls [ lang ] . dic , true )
64
- xhrDic . onload = ( ) => {
65
- if ( xhrDic . readyState === 4 && xhrDic . status === 200 ) {
66
- this . dicData = xhrDic . responseText
67
- this . numLoaded ++
68
-
69
- if ( this . numLoaded === 2 ) {
70
- this . typo = new Typo ( lang , this . affData , this . dicData , { platform : 'any' } )
71
- }
72
- }
73
- }
74
- xhrDic . send ( null )
75
- }
85
+ // Load AFF/DIC data async
86
+ findOrCreateTypoInstance ( lang ) . then ( typo => { this . typo = typo } )
76
87
77
88
// Define what separates a word
78
89
const regexWord = '!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~ '
@@ -108,5 +119,4 @@ class CodeMirrorSpellChecker {
108
119
}
109
120
}
110
121
111
- // Export
112
122
export default CodeMirrorSpellChecker
0 commit comments