Skip to content

Commit 19dad9d

Browse files
committed
Lazy load dicts, support cdn, config webpack
Signed-off-by: Yukai Huang <[email protected]>
1 parent 2244387 commit 19dad9d

File tree

8 files changed

+141
-32
lines changed

8 files changed

+141
-32
lines changed

lib/status/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ exports.getConfig = (req, res) => {
2424
DROPBOX_APP_KEY: config.dropbox.appKey,
2525
allowedUploadMimeTypes: config.allowedUploadMimeTypes,
2626
defaultUseHardbreak: config.defaultUseHardbreak,
27-
linkifyHeaderStyle: config.linkifyHeaderStyle
27+
linkifyHeaderStyle: config.linkifyHeaderStyle,
28+
useCDN: config.useCDN
2829
}
2930
res.set({
3031
'Cache-Control': 'private', // only cache by client

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@
165165
"babel-runtime": "~6.26.0",
166166
"copy-webpack-plugin": "~4.5.2",
167167
"css-loader": "~1.0.0",
168+
"dictionary-de": "^2.0.3",
169+
"dictionary-de-at": "^2.0.3",
170+
"dictionary-de-ch": "^2.0.3",
168171
"doctoc": "~1.4.0",
169172
"ejs-loader": "~0.3.1",
170173
"exports-loader": "~0.7.0",

public/js/lib/common/constant.ejs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ window.defaultUseHardbreak = <%- defaultUseHardbreak %>
1111
window.linkifyHeaderStyle = '<%- linkifyHeaderStyle %>'
1212

1313
window.DROPBOX_APP_KEY = '<%- DROPBOX_APP_KEY %>'
14+
15+
window.USE_CDN = <%- useCDN %>

public/js/lib/editor/index.js

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import config from './config'
77
import statusBarTemplate from './statusbar.html'
88
import toolBarTemplate from './toolbar.html'
99
import './markdown-lint'
10-
import CodeMirrorSpellChecker, { supportLanguages } from './spellcheck'
10+
import CodeMirrorSpellChecker, { supportLanguages, supportLanguageCodes } from './spellcheck'
1111
import { initTableEditor } from './table-editor'
1212
import { availableThemes } from './constants'
1313

@@ -548,7 +548,7 @@ export default class Editor {
548548
return
549549
}
550550

551-
if (!supportLanguages.includes(lang)) {
551+
if (!supportLanguageCodes.includes(lang)) {
552552
return
553553
}
554554

@@ -558,7 +558,21 @@ export default class Editor {
558558
this.spellchecker.setDictLang(lang)
559559
}
560560

561+
getExistingSpellcheckLang () {
562+
const cookieSpellcheck = Cookies.get('spellcheck')
563+
564+
if (cookieSpellcheck) {
565+
return cookieSpellcheck === 'false' ? undefined : cookieSpellcheck
566+
} else {
567+
return undefined
568+
}
569+
}
570+
561571
setSpellcheck () {
572+
this.statusSpellcheck.find('ul.dropdown-menu').append(supportLanguages.map(lang => {
573+
return $(`<li value="${lang.value}"><a>${lang.name}</a></li>`)
574+
}))
575+
562576
const cookieSpellcheck = Cookies.get('spellcheck')
563577
if (cookieSpellcheck) {
564578
let mode = null
@@ -567,7 +581,7 @@ export default class Editor {
567581
mode = defaultEditorMode
568582
} else {
569583
mode = 'spell-checker'
570-
if (supportLanguages.includes(cookieSpellcheck)) {
584+
if (supportLanguageCodes.includes(cookieSpellcheck)) {
571585
lang = cookieSpellcheck
572586
}
573587
}
@@ -740,7 +754,7 @@ export default class Editor {
740754
placeholder: "← Start by entering a title here\n===\nVisit /features if you don't know what to do.\nHappy hacking :)"
741755
})
742756

743-
this.spellchecker = new CodeMirrorSpellChecker(CodeMirror)
757+
this.spellchecker = new CodeMirrorSpellChecker(CodeMirror, this.getExistingSpellcheckLang())
744758
this.tableEditor = initTableEditor(this.editor)
745759

746760
return this.editor

public/js/lib/editor/spellcheck.js

Lines changed: 85 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,58 @@
55
import Typo from 'typo-js'
66
import { serverurl } from '../config'
77

8-
const dictionaryDownloadUrls = {
9-
en_US: {
10-
aff: `${serverurl}/vendor/codemirror-spell-checker/en_US.aff`,
11-
dic: `${serverurl}/vendor/codemirror-spell-checker/en_US.dic`
8+
export const supportLanguages = [
9+
{
10+
name: 'English (United States)',
11+
value: 'en_US',
12+
aff: {
13+
url: `${serverurl}/vendor/codemirror-spell-checker/en_US.aff`,
14+
cdnUrl: `${serverurl}/vendor/codemirror-spell-checker/en_US.aff`
15+
},
16+
dic: {
17+
url: `${serverurl}/vendor/codemirror-spell-checker/en_US.dic`,
18+
cdnUrl: `${serverurl}/vendor/codemirror-spell-checker/en_US.dic`
19+
}
1220
},
13-
de: {
14-
aff: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de/index.aff',
15-
dic: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de/index.dic'
21+
{
22+
name: 'German',
23+
value: 'de',
24+
aff: {
25+
url: `${serverurl}/build/dictionary-de/index.aff`,
26+
cdnUrl: `https://cdn.jsdelivr.net/npm/[email protected]/index.aff`
27+
},
28+
dic: {
29+
url: `${serverurl}/build/dictionary-de/index.dic`,
30+
cdnUrl: `https://cdn.jsdelivr.net/npm/[email protected]/index.dic`
31+
}
1632
},
17-
de_AT: {
18-
aff: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-AT/index.aff',
19-
dic: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-AT/index.dic'
33+
{
34+
name: 'German (Austria)',
35+
value: 'de_AT',
36+
aff: {
37+
url: `${serverurl}/build/dictionary-de-at/index.aff`,
38+
cdnUrl: `https://cdn.jsdelivr.net/npm/[email protected]/index.aff`
39+
},
40+
dic: {
41+
url: `${serverurl}/build/dictionary-de-at/index.dic`,
42+
cdnUrl: `https://cdn.jsdelivr.net/npm/[email protected]/index.dic`
43+
}
2044
},
21-
de_CH: {
22-
aff: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-CH/index.aff',
23-
dic: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-CH/index.dic'
45+
{
46+
name: 'German (Switzerland)',
47+
value: 'de_CH',
48+
aff: {
49+
url: `${serverurl}/build/dictionary-de-ch/index.aff`,
50+
cdnUrl: `https://cdn.jsdelivr.net/npm/[email protected]/index.aff`
51+
},
52+
dic: {
53+
url: `${serverurl}/build/dictionary-de-ch/index.dic`,
54+
cdnUrl: `https://cdn.jsdelivr.net/npm/[email protected]/index.dic`
55+
}
2456
}
25-
}
57+
]
2658

27-
export const supportLanguages = Object.keys(dictionaryDownloadUrls)
59+
export const supportLanguageCodes = supportLanguages.map(lang => lang.value)
2860

2961
function request (url) {
3062
return new Promise(resolve => {
@@ -59,20 +91,51 @@ function createTypo (lang, affData, dicData) {
5991

6092
const typoMap = new Map()
6193

94+
let fetching = false
6295
async function findOrCreateTypoInstance (lang) {
96+
if (!lang) {
97+
return
98+
}
99+
63100
// find existing typo instance
64101
let typo = typoMap.get(lang)
65102
if (typo) {
66103
return typo
67104
}
68105

69-
const [affData, dicData] = await mapSeriesP([
70-
dictionaryDownloadUrls[lang].aff,
71-
dictionaryDownloadUrls[lang].dic
72-
], request)
106+
let dict = supportLanguages.find(l => l.value === lang)
107+
108+
if (!dict) {
109+
console.error(`Dictionary not found for "${lang}"\n Fallback to default English spellcheck`)
110+
dict = supportLanguages[0]
111+
}
73112

74-
typo = createTypo(lang, affData, dicData)
75-
typoMap.set(lang, typo)
113+
let affUrl
114+
let dicUrl
115+
if (window.USE_CDN) {
116+
affUrl = dict.aff.cdnUrl
117+
dicUrl = dict.dic.cdnUrl
118+
} else {
119+
affUrl = dict.aff.url
120+
dicUrl = dict.dic.url
121+
}
122+
123+
if (fetching) {
124+
return typo
125+
}
126+
127+
try {
128+
fetching = true
129+
130+
const [affData, dicData] = await mapSeriesP([affUrl, dicUrl], request)
131+
132+
typo = createTypo(lang, affData, dicData)
133+
typoMap.set(lang, typo)
134+
} catch (err) {
135+
console.error(err)
136+
} finally {
137+
fetching = false
138+
}
76139

77140
return typo
78141
}
@@ -82,7 +145,7 @@ class CodeMirrorSpellChecker {
82145
* @param {CodeMirror} cm
83146
* @param {string} lang
84147
*/
85-
constructor (cm, lang = 'en_US') {
148+
constructor (cm, lang) {
86149
// Verify
87150
if (typeof cm !== 'function' || typeof cm.defineMode !== 'function') {
88151
console.log(

public/js/lib/editor/statusbar.html

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,6 @@
4545
</a>
4646
<ul class="dropdown-menu" aria-labelledby="themeLabel">
4747
<li value="disabled"><a>Disabled</a></li>
48-
<li value="en_US"><a>English (United States)</a></li>
49-
<li value="de"><a>German</a></li>
50-
<li value="de_AT"><a>German (Austria)</a></li>
51-
<li value="de_CH"><a>German (Switzerland)</a></li>
5248
</ul>
5349
</div>
5450
<div class="status-linter">

webpack.common.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,22 @@ module.exports = {
165165
context: path.join(__dirname, 'node_modules/reveal.js'),
166166
from: 'plugin',
167167
to: 'reveal.js/plugin'
168-
}
168+
},
169+
{
170+
context: path.join(__dirname, 'node_modules/dictionary-de'),
171+
from: '*',
172+
to: 'dictionary-de/'
173+
},
174+
{
175+
context: path.join(__dirname, 'node_modules/dictionary-de-at'),
176+
from: '*',
177+
to: 'dictionary-de-at/'
178+
},
179+
{
180+
context: path.join(__dirname, 'node_modules/dictionary-de-ch'),
181+
from: '*',
182+
to: 'dictionary-de-ch/'
183+
},
169184
]),
170185
new MiniCssExtractPlugin()
171186
],

yarn.lock

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4333,6 +4333,21 @@ diagnostics@^1.1.1:
43334333
enabled "1.0.x"
43344334
kuler "1.0.x"
43354335

4336+
dictionary-de-at@^2.0.3:
4337+
version "2.0.3"
4338+
resolved "https://registry.yarnpkg.com/dictionary-de-at/-/dictionary-de-at-2.0.3.tgz#78f31d0cd8ca7c7d5ba48fdefb7a7bd3f05e11ca"
4339+
integrity sha512-unbay9PPM75yZ0RPnqSD/PADpZj7/vPDVeau2jTsVPFKwhoZGJTBVLD2wCaIkhS6tyVsNOboo1VYjzOCOit2ww==
4340+
4341+
dictionary-de-ch@^2.0.3:
4342+
version "2.0.3"
4343+
resolved "https://registry.yarnpkg.com/dictionary-de-ch/-/dictionary-de-ch-2.0.3.tgz#1727413a1eb35eb78e7fe15b5b7a742fd650f0c3"
4344+
integrity sha512-+eqpz5j8WONSzxmc4avCN4XX/6q5+J6JfWz2AaluZIOVNgXPxUjXBhKS73+nRhM3nE1pGeRMqkyZevTQWgYTTw==
4345+
4346+
dictionary-de@^2.0.3:
4347+
version "2.0.3"
4348+
resolved "https://registry.yarnpkg.com/dictionary-de/-/dictionary-de-2.0.3.tgz#df50c749fddbff601f5bd044aef4622a365a15b2"
4349+
integrity sha512-fbNcCIjDrdNvu7DzMzkOY77vIaGqiDQqf9vtwGud1fcSxVWwX6EdtHcosmgG7AA10u3QgDVkymMaX9mr3elwRw==
4350+
43364351
diff-match-patch@^1.0.0:
43374352
version "1.0.4"
43384353
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.4.tgz#6ac4b55237463761c4daf0dc603eb869124744b1"

0 commit comments

Comments
 (0)