@@ -12,6 +12,56 @@ const dictionaryDownloadUrls = {
1212 }
1313}
1414
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+
1565class CodeMirrorSpellChecker {
1666 /**
1767 * @param {CodeMirror } cm
@@ -26,53 +76,14 @@ class CodeMirrorSpellChecker {
2676 return
2777 }
2878
29- this . numLoaded = 0
30- this . affLoading = false
31- this . dicLoading = false
32- this . affData = ''
33- this . dicData = ''
3479 this . typo = undefined
35-
36- this . setupCM . bind ( this ) ( cm , lang )
80+ this . setupCM ( cm , lang )
3781 }
3882
3983 setupCM ( cm , lang ) {
4084 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 } )
7687
7788 // Define what separates a word
7889 const regexWord = '!"#$%&()*+,-./:;<=>?@[\\]^_`{|}~ '
@@ -108,5 +119,4 @@ class CodeMirrorSpellChecker {
108119 }
109120}
110121
111- // Export
112122export default CodeMirrorSpellChecker
0 commit comments