diff options
Diffstat (limited to 'src/webview/recipe.js')
-rw-r--r-- | src/webview/recipe.js | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/src/webview/recipe.js b/src/webview/recipe.js index c718b348e..1e5d74b1f 100644 --- a/src/webview/recipe.js +++ b/src/webview/recipe.js | |||
@@ -1,10 +1,12 @@ | |||
1 | import { ipcRenderer } from 'electron'; | 1 | import { ipcRenderer } from 'electron'; |
2 | import path from 'path'; | 2 | import path from 'path'; |
3 | import { autorun, computed, observable } from 'mobx'; | 3 | import { autorun, computed, observable } from 'mobx'; |
4 | import { loadModule } from 'cld3-asm'; | ||
5 | import { debounce } from 'lodash'; | ||
4 | 6 | ||
5 | import RecipeWebview from './lib/RecipeWebview'; | 7 | import RecipeWebview from './lib/RecipeWebview'; |
6 | 8 | ||
7 | import spellchecker, { switchDict, disable as disableSpellchecker } from './spellchecker'; | 9 | import spellchecker, { switchDict, disable as disableSpellchecker, getSpellcheckerLocaleByFuzzyIdentifier } from './spellchecker'; |
8 | import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode'; | 10 | import { injectDarkModeStyle, isDarkModeStyleInjected, removeDarkModeStyle } from './darkmode'; |
9 | import contextMenu from './contextMenu'; | 11 | import contextMenu from './contextMenu'; |
10 | import './notifications'; | 12 | import './notifications'; |
@@ -40,6 +42,8 @@ class RecipeController { | |||
40 | return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; | 42 | return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; |
41 | } | 43 | } |
42 | 44 | ||
45 | cldIdentifier = null; | ||
46 | |||
43 | async initialize() { | 47 | async initialize() { |
44 | Object.keys(this.ipcEvents).forEach((channel) => { | 48 | Object.keys(this.ipcEvents).forEach((channel) => { |
45 | ipcRenderer.on(channel, (...args) => { | 49 | ipcRenderer.on(channel, (...args) => { |
@@ -87,10 +91,22 @@ class RecipeController { | |||
87 | 91 | ||
88 | if (this.settings.app.enableSpellchecking) { | 92 | if (this.settings.app.enableSpellchecking) { |
89 | debug('Setting spellchecker language to', this.spellcheckerLanguage); | 93 | debug('Setting spellchecker language to', this.spellcheckerLanguage); |
90 | switchDict(this.spellcheckerLanguage); | 94 | let { spellcheckerLanguage } = this; |
95 | if (spellcheckerLanguage === 'automatic') { | ||
96 | this.automaticLanguageDetection(); | ||
97 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); | ||
98 | spellcheckerLanguage = this.settings.app.locale; | ||
99 | } else if (this.cldIdentifier) { | ||
100 | this.cldIdentifier.destroy(); | ||
101 | } | ||
102 | switchDict(spellcheckerLanguage); | ||
91 | } else { | 103 | } else { |
92 | debug('Disable spellchecker'); | 104 | debug('Disable spellchecker'); |
93 | disableSpellchecker(); | 105 | disableSpellchecker(); |
106 | |||
107 | if (this.cldIdentifier) { | ||
108 | this.cldIdentifier.destroy(); | ||
109 | } | ||
94 | } | 110 | } |
95 | 111 | ||
96 | if (this.settings.service.isDarkModeEnabled) { | 112 | if (this.settings.service.isDarkModeEnabled) { |
@@ -113,6 +129,42 @@ class RecipeController { | |||
113 | serviceIdEcho(event) { | 129 | serviceIdEcho(event) { |
114 | event.sender.send('service-id', this.settings.service.id); | 130 | event.sender.send('service-id', this.settings.service.id); |
115 | } | 131 | } |
132 | |||
133 | async automaticLanguageDetection() { | ||
134 | const cldFactory = await loadModule(); | ||
135 | this.cldIdentifier = cldFactory.create(0, 1000); | ||
136 | |||
137 | window.addEventListener('keyup', debounce((e) => { | ||
138 | const element = e.target; | ||
139 | |||
140 | console.log(element); | ||
141 | |||
142 | if (!element) return; | ||
143 | |||
144 | let value = ''; | ||
145 | if (element.isContentEditable) { | ||
146 | value = element.textContent; | ||
147 | } else if (element.value) { | ||
148 | value = element.value; | ||
149 | } | ||
150 | |||
151 | // Force a minimum length to get better detection results | ||
152 | if (value.length < 30) return; | ||
153 | |||
154 | debug('Detecting language for', value); | ||
155 | const findResult = this.cldIdentifier.findLanguage(value); | ||
156 | |||
157 | debug('Language detection result', findResult); | ||
158 | |||
159 | if (findResult.is_reliable) { | ||
160 | const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); | ||
161 | debug('Language detected reliably, setting spellchecker language to', spellcheckerLocale); | ||
162 | if (spellcheckerLocale) { | ||
163 | switchDict(spellcheckerLocale); | ||
164 | } | ||
165 | } | ||
166 | }, 225)); | ||
167 | } | ||
116 | } | 168 | } |
117 | 169 | ||
118 | /* eslint-disable no-new */ | 170 | /* eslint-disable no-new */ |