diff options
author | 2019-02-08 11:32:20 +0100 | |
---|---|---|
committer | 2019-02-08 11:32:20 +0100 | |
commit | e2437f27ccd1c7646accc75b819fff3295c7a2e2 (patch) | |
tree | b291106a314e66fe77f11bb9026e12c1bb5839b0 /src/webview | |
parent | Remove debugging output (diff) | |
download | ferdium-app-e2437f27ccd1c7646accc75b819fff3295c7a2e2.tar.gz ferdium-app-e2437f27ccd1c7646accc75b819fff3295c7a2e2.tar.zst ferdium-app-e2437f27ccd1c7646accc75b819fff3295c7a2e2.zip |
feat(Spell checking): Add option to automatically detect language
Diffstat (limited to 'src/webview')
-rw-r--r-- | src/webview/contextMenu.js | 11 | ||||
-rw-r--r-- | src/webview/recipe.js | 76 |
2 files changed, 50 insertions, 37 deletions
diff --git a/src/webview/contextMenu.js b/src/webview/contextMenu.js index 75915851d..afb1d8912 100644 --- a/src/webview/contextMenu.js +++ b/src/webview/contextMenu.js | |||
@@ -232,20 +232,19 @@ const buildMenuTpl = (props, suggestions, isSpellcheckEnabled, defaultSpellcheck | |||
232 | }, | 232 | }, |
233 | }, | 233 | }, |
234 | { | 234 | { |
235 | type: 'separator', | ||
236 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | ||
237 | }, | ||
238 | { | ||
239 | id: 'automaticDetection', | 235 | id: 'automaticDetection', |
240 | label: 'Automatic language detection', | 236 | label: 'Automatic language detection', |
241 | type: 'radio', | 237 | type: 'radio', |
242 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | ||
243 | checked: spellcheckerLanguage === 'automatic', | 238 | checked: spellcheckerLanguage === 'automatic', |
244 | click() { | 239 | click() { |
245 | debug('Detect spellchecker language automatically'); | 240 | debug('Detect language automatically'); |
246 | ipcRenderer.sendToHost('set-service-spellchecker-language', 'automatic'); | 241 | ipcRenderer.sendToHost('set-service-spellchecker-language', 'automatic'); |
247 | }, | 242 | }, |
248 | }, | 243 | }, |
244 | { | ||
245 | type: 'separator', | ||
246 | visible: defaultSpellcheckerLanguage !== spellcheckerLanguage, | ||
247 | }, | ||
249 | ...spellcheckingLanguages], | 248 | ...spellcheckingLanguages], |
250 | }); | 249 | }); |
251 | 250 | ||
diff --git a/src/webview/recipe.js b/src/webview/recipe.js index fa107ba1a..1e5d74b1f 100644 --- a/src/webview/recipe.js +++ b/src/webview/recipe.js | |||
@@ -42,6 +42,8 @@ class RecipeController { | |||
42 | return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; | 42 | return this.settings.service.spellcheckerLanguage || this.settings.app.spellcheckerLanguage; |
43 | } | 43 | } |
44 | 44 | ||
45 | cldIdentifier = null; | ||
46 | |||
45 | async initialize() { | 47 | async initialize() { |
46 | Object.keys(this.ipcEvents).forEach((channel) => { | 48 | Object.keys(this.ipcEvents).forEach((channel) => { |
47 | ipcRenderer.on(channel, (...args) => { | 49 | ipcRenderer.on(channel, (...args) => { |
@@ -62,37 +64,6 @@ class RecipeController { | |||
62 | ); | 64 | ); |
63 | 65 | ||
64 | autorun(() => this.update()); | 66 | autorun(() => this.update()); |
65 | |||
66 | const cldFactory = await loadModule(); | ||
67 | const identifier = cldFactory.create(0, 1000); | ||
68 | |||
69 | window.addEventListener('keyup', debounce((e) => { | ||
70 | const elem = e.target; | ||
71 | |||
72 | let value = ''; | ||
73 | if (elem.isContentEditable) { | ||
74 | value = elem.textContent; | ||
75 | } else { | ||
76 | // | ||
77 | } | ||
78 | |||
79 | // Force a minimum length to get better detection results | ||
80 | if (value.length < 40) return; | ||
81 | |||
82 | debug('Detecting language for', value); | ||
83 | const findResult = identifier.findLanguage(value); | ||
84 | |||
85 | debug('Language detection result', findResult); | ||
86 | |||
87 | if (findResult.is_reliable) { | ||
88 | debug('Language detected reliably, setting spellchecker language to', findResult.language); | ||
89 | const spellcheckerLocale = getSpellcheckerLocaleByFuzzyIdentifier(findResult.language); | ||
90 | debug('reported back', spellcheckerLocale); | ||
91 | if (spellcheckerLocale) { | ||
92 | switchDict(spellcheckerLocale); | ||
93 | } | ||
94 | } | ||
95 | }, 200)); | ||
96 | } | 67 | } |
97 | 68 | ||
98 | loadRecipeModule(event, config, recipe) { | 69 | loadRecipeModule(event, config, recipe) { |
@@ -122,13 +93,20 @@ class RecipeController { | |||
122 | debug('Setting spellchecker language to', this.spellcheckerLanguage); | 93 | debug('Setting spellchecker language to', this.spellcheckerLanguage); |
123 | let { spellcheckerLanguage } = this; | 94 | let { spellcheckerLanguage } = this; |
124 | if (spellcheckerLanguage === 'automatic') { | 95 | if (spellcheckerLanguage === 'automatic') { |
96 | this.automaticLanguageDetection(); | ||
125 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); | 97 | debug('Found `automatic` locale, falling back to user locale until detected', this.settings.app.locale); |
126 | spellcheckerLanguage = this.settings.app.locale; | 98 | spellcheckerLanguage = this.settings.app.locale; |
99 | } else if (this.cldIdentifier) { | ||
100 | this.cldIdentifier.destroy(); | ||
127 | } | 101 | } |
128 | switchDict(spellcheckerLanguage); | 102 | switchDict(spellcheckerLanguage); |
129 | } else { | 103 | } else { |
130 | debug('Disable spellchecker'); | 104 | debug('Disable spellchecker'); |
131 | disableSpellchecker(); | 105 | disableSpellchecker(); |
106 | |||
107 | if (this.cldIdentifier) { | ||
108 | this.cldIdentifier.destroy(); | ||
109 | } | ||
132 | } | 110 | } |
133 | 111 | ||
134 | if (this.settings.service.isDarkModeEnabled) { | 112 | if (this.settings.service.isDarkModeEnabled) { |
@@ -151,6 +129,42 @@ class RecipeController { | |||
151 | serviceIdEcho(event) { | 129 | serviceIdEcho(event) { |
152 | event.sender.send('service-id', this.settings.service.id); | 130 | event.sender.send('service-id', this.settings.service.id); |
153 | } | 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 | } | ||
154 | } | 168 | } |
155 | 169 | ||
156 | /* eslint-disable no-new */ | 170 | /* eslint-disable no-new */ |