mirror of https://github.com/status-im/codimd.git
Lazy load dicts, support cdn, config webpack
Signed-off-by: Yukai Huang <yukaihuangtw@gmail.com>
This commit is contained in:
parent
22443879e7
commit
19dad9dfc8
|
@ -24,7 +24,8 @@ exports.getConfig = (req, res) => {
|
|||
DROPBOX_APP_KEY: config.dropbox.appKey,
|
||||
allowedUploadMimeTypes: config.allowedUploadMimeTypes,
|
||||
defaultUseHardbreak: config.defaultUseHardbreak,
|
||||
linkifyHeaderStyle: config.linkifyHeaderStyle
|
||||
linkifyHeaderStyle: config.linkifyHeaderStyle,
|
||||
useCDN: config.useCDN
|
||||
}
|
||||
res.set({
|
||||
'Cache-Control': 'private', // only cache by client
|
||||
|
|
|
@ -165,6 +165,9 @@
|
|||
"babel-runtime": "~6.26.0",
|
||||
"copy-webpack-plugin": "~4.5.2",
|
||||
"css-loader": "~1.0.0",
|
||||
"dictionary-de": "^2.0.3",
|
||||
"dictionary-de-at": "^2.0.3",
|
||||
"dictionary-de-ch": "^2.0.3",
|
||||
"doctoc": "~1.4.0",
|
||||
"ejs-loader": "~0.3.1",
|
||||
"exports-loader": "~0.7.0",
|
||||
|
|
|
@ -11,3 +11,5 @@ window.defaultUseHardbreak = <%- defaultUseHardbreak %>
|
|||
window.linkifyHeaderStyle = '<%- linkifyHeaderStyle %>'
|
||||
|
||||
window.DROPBOX_APP_KEY = '<%- DROPBOX_APP_KEY %>'
|
||||
|
||||
window.USE_CDN = <%- useCDN %>
|
||||
|
|
|
@ -7,7 +7,7 @@ import config from './config'
|
|||
import statusBarTemplate from './statusbar.html'
|
||||
import toolBarTemplate from './toolbar.html'
|
||||
import './markdown-lint'
|
||||
import CodeMirrorSpellChecker, { supportLanguages } from './spellcheck'
|
||||
import CodeMirrorSpellChecker, { supportLanguages, supportLanguageCodes } from './spellcheck'
|
||||
import { initTableEditor } from './table-editor'
|
||||
import { availableThemes } from './constants'
|
||||
|
||||
|
@ -548,7 +548,7 @@ export default class Editor {
|
|||
return
|
||||
}
|
||||
|
||||
if (!supportLanguages.includes(lang)) {
|
||||
if (!supportLanguageCodes.includes(lang)) {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -558,7 +558,21 @@ export default class Editor {
|
|||
this.spellchecker.setDictLang(lang)
|
||||
}
|
||||
|
||||
getExistingSpellcheckLang () {
|
||||
const cookieSpellcheck = Cookies.get('spellcheck')
|
||||
|
||||
if (cookieSpellcheck) {
|
||||
return cookieSpellcheck === 'false' ? undefined : cookieSpellcheck
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
setSpellcheck () {
|
||||
this.statusSpellcheck.find('ul.dropdown-menu').append(supportLanguages.map(lang => {
|
||||
return $(`<li value="${lang.value}"><a>${lang.name}</a></li>`)
|
||||
}))
|
||||
|
||||
const cookieSpellcheck = Cookies.get('spellcheck')
|
||||
if (cookieSpellcheck) {
|
||||
let mode = null
|
||||
|
@ -567,7 +581,7 @@ export default class Editor {
|
|||
mode = defaultEditorMode
|
||||
} else {
|
||||
mode = 'spell-checker'
|
||||
if (supportLanguages.includes(cookieSpellcheck)) {
|
||||
if (supportLanguageCodes.includes(cookieSpellcheck)) {
|
||||
lang = cookieSpellcheck
|
||||
}
|
||||
}
|
||||
|
@ -740,7 +754,7 @@ export default class Editor {
|
|||
placeholder: "← Start by entering a title here\n===\nVisit /features if you don't know what to do.\nHappy hacking :)"
|
||||
})
|
||||
|
||||
this.spellchecker = new CodeMirrorSpellChecker(CodeMirror)
|
||||
this.spellchecker = new CodeMirrorSpellChecker(CodeMirror, this.getExistingSpellcheckLang())
|
||||
this.tableEditor = initTableEditor(this.editor)
|
||||
|
||||
return this.editor
|
||||
|
|
|
@ -5,26 +5,58 @@
|
|||
import Typo from 'typo-js'
|
||||
import { serverurl } from '../config'
|
||||
|
||||
const dictionaryDownloadUrls = {
|
||||
en_US: {
|
||||
aff: `${serverurl}/vendor/codemirror-spell-checker/en_US.aff`,
|
||||
dic: `${serverurl}/vendor/codemirror-spell-checker/en_US.dic`
|
||||
export const supportLanguages = [
|
||||
{
|
||||
name: 'English (United States)',
|
||||
value: 'en_US',
|
||||
aff: {
|
||||
url: `${serverurl}/vendor/codemirror-spell-checker/en_US.aff`,
|
||||
cdnUrl: `${serverurl}/vendor/codemirror-spell-checker/en_US.aff`
|
||||
},
|
||||
dic: {
|
||||
url: `${serverurl}/vendor/codemirror-spell-checker/en_US.dic`,
|
||||
cdnUrl: `${serverurl}/vendor/codemirror-spell-checker/en_US.dic`
|
||||
}
|
||||
},
|
||||
de: {
|
||||
aff: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de/index.aff',
|
||||
dic: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de/index.dic'
|
||||
{
|
||||
name: 'German',
|
||||
value: 'de',
|
||||
aff: {
|
||||
url: `${serverurl}/build/dictionary-de/index.aff`,
|
||||
cdnUrl: `https://cdn.jsdelivr.net/npm/dictionary-de@2.0.3/index.aff`
|
||||
},
|
||||
dic: {
|
||||
url: `${serverurl}/build/dictionary-de/index.dic`,
|
||||
cdnUrl: `https://cdn.jsdelivr.net/npm/dictionary-de@2.0.3/index.dic`
|
||||
}
|
||||
},
|
||||
de_AT: {
|
||||
aff: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-AT/index.aff',
|
||||
dic: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-AT/index.dic'
|
||||
{
|
||||
name: 'German (Austria)',
|
||||
value: 'de_AT',
|
||||
aff: {
|
||||
url: `${serverurl}/build/dictionary-de-at/index.aff`,
|
||||
cdnUrl: `https://cdn.jsdelivr.net/npm/dictionary-de-at@2.0.3/index.aff`
|
||||
},
|
||||
dic: {
|
||||
url: `${serverurl}/build/dictionary-de-at/index.dic`,
|
||||
cdnUrl: `https://cdn.jsdelivr.net/npm/dictionary-de-at@2.0.3/index.dic`
|
||||
}
|
||||
},
|
||||
de_CH: {
|
||||
aff: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-CH/index.aff',
|
||||
dic: 'https://rawcdn.githack.com/wooorm/dictionaries/143091715eebbbdfa0e8936e117f9182514eebe6/dictionaries/de-CH/index.dic'
|
||||
{
|
||||
name: 'German (Switzerland)',
|
||||
value: 'de_CH',
|
||||
aff: {
|
||||
url: `${serverurl}/build/dictionary-de-ch/index.aff`,
|
||||
cdnUrl: `https://cdn.jsdelivr.net/npm/dictionary-de-ch@2.0.3/index.aff`
|
||||
},
|
||||
dic: {
|
||||
url: `${serverurl}/build/dictionary-de-ch/index.dic`,
|
||||
cdnUrl: `https://cdn.jsdelivr.net/npm/dictionary-de-ch@2.0.3/index.dic`
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
export const supportLanguages = Object.keys(dictionaryDownloadUrls)
|
||||
export const supportLanguageCodes = supportLanguages.map(lang => lang.value)
|
||||
|
||||
function request (url) {
|
||||
return new Promise(resolve => {
|
||||
|
@ -59,20 +91,51 @@ function createTypo (lang, affData, dicData) {
|
|||
|
||||
const typoMap = new Map()
|
||||
|
||||
let fetching = false
|
||||
async function findOrCreateTypoInstance (lang) {
|
||||
if (!lang) {
|
||||
return
|
||||
}
|
||||
|
||||
// find existing typo instance
|
||||
let typo = typoMap.get(lang)
|
||||
if (typo) {
|
||||
return typo
|
||||
}
|
||||
|
||||
const [affData, dicData] = await mapSeriesP([
|
||||
dictionaryDownloadUrls[lang].aff,
|
||||
dictionaryDownloadUrls[lang].dic
|
||||
], request)
|
||||
let dict = supportLanguages.find(l => l.value === lang)
|
||||
|
||||
typo = createTypo(lang, affData, dicData)
|
||||
typoMap.set(lang, typo)
|
||||
if (!dict) {
|
||||
console.error(`Dictionary not found for "${lang}"\n Fallback to default English spellcheck`)
|
||||
dict = supportLanguages[0]
|
||||
}
|
||||
|
||||
let affUrl
|
||||
let dicUrl
|
||||
if (window.USE_CDN) {
|
||||
affUrl = dict.aff.cdnUrl
|
||||
dicUrl = dict.dic.cdnUrl
|
||||
} else {
|
||||
affUrl = dict.aff.url
|
||||
dicUrl = dict.dic.url
|
||||
}
|
||||
|
||||
if (fetching) {
|
||||
return typo
|
||||
}
|
||||
|
||||
try {
|
||||
fetching = true
|
||||
|
||||
const [affData, dicData] = await mapSeriesP([affUrl, dicUrl], request)
|
||||
|
||||
typo = createTypo(lang, affData, dicData)
|
||||
typoMap.set(lang, typo)
|
||||
} catch (err) {
|
||||
console.error(err)
|
||||
} finally {
|
||||
fetching = false
|
||||
}
|
||||
|
||||
return typo
|
||||
}
|
||||
|
@ -82,7 +145,7 @@ class CodeMirrorSpellChecker {
|
|||
* @param {CodeMirror} cm
|
||||
* @param {string} lang
|
||||
*/
|
||||
constructor (cm, lang = 'en_US') {
|
||||
constructor (cm, lang) {
|
||||
// Verify
|
||||
if (typeof cm !== 'function' || typeof cm.defineMode !== 'function') {
|
||||
console.log(
|
||||
|
|
|
@ -45,10 +45,6 @@
|
|||
</a>
|
||||
<ul class="dropdown-menu" aria-labelledby="themeLabel">
|
||||
<li value="disabled"><a>Disabled</a></li>
|
||||
<li value="en_US"><a>English (United States)</a></li>
|
||||
<li value="de"><a>German</a></li>
|
||||
<li value="de_AT"><a>German (Austria)</a></li>
|
||||
<li value="de_CH"><a>German (Switzerland)</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="status-linter">
|
||||
|
|
|
@ -165,7 +165,22 @@ module.exports = {
|
|||
context: path.join(__dirname, 'node_modules/reveal.js'),
|
||||
from: 'plugin',
|
||||
to: 'reveal.js/plugin'
|
||||
}
|
||||
},
|
||||
{
|
||||
context: path.join(__dirname, 'node_modules/dictionary-de'),
|
||||
from: '*',
|
||||
to: 'dictionary-de/'
|
||||
},
|
||||
{
|
||||
context: path.join(__dirname, 'node_modules/dictionary-de-at'),
|
||||
from: '*',
|
||||
to: 'dictionary-de-at/'
|
||||
},
|
||||
{
|
||||
context: path.join(__dirname, 'node_modules/dictionary-de-ch'),
|
||||
from: '*',
|
||||
to: 'dictionary-de-ch/'
|
||||
},
|
||||
]),
|
||||
new MiniCssExtractPlugin()
|
||||
],
|
||||
|
|
15
yarn.lock
15
yarn.lock
|
@ -4333,6 +4333,21 @@ diagnostics@^1.1.1:
|
|||
enabled "1.0.x"
|
||||
kuler "1.0.x"
|
||||
|
||||
dictionary-de-at@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dictionary-de-at/-/dictionary-de-at-2.0.3.tgz#78f31d0cd8ca7c7d5ba48fdefb7a7bd3f05e11ca"
|
||||
integrity sha512-unbay9PPM75yZ0RPnqSD/PADpZj7/vPDVeau2jTsVPFKwhoZGJTBVLD2wCaIkhS6tyVsNOboo1VYjzOCOit2ww==
|
||||
|
||||
dictionary-de-ch@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dictionary-de-ch/-/dictionary-de-ch-2.0.3.tgz#1727413a1eb35eb78e7fe15b5b7a742fd650f0c3"
|
||||
integrity sha512-+eqpz5j8WONSzxmc4avCN4XX/6q5+J6JfWz2AaluZIOVNgXPxUjXBhKS73+nRhM3nE1pGeRMqkyZevTQWgYTTw==
|
||||
|
||||
dictionary-de@^2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/dictionary-de/-/dictionary-de-2.0.3.tgz#df50c749fddbff601f5bd044aef4622a365a15b2"
|
||||
integrity sha512-fbNcCIjDrdNvu7DzMzkOY77vIaGqiDQqf9vtwGud1fcSxVWwX6EdtHcosmgG7AA10u3QgDVkymMaX9mr3elwRw==
|
||||
|
||||
diff-match-patch@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/diff-match-patch/-/diff-match-patch-1.0.4.tgz#6ac4b55237463761c4daf0dc603eb869124744b1"
|
||||
|
|
Loading…
Reference in New Issue