文件
mynode/packages/app-desktop/services/spellChecker/SpellCheckerServiceDriverNative.ts
chen 301194963b
一些检查失败了
automerge / automerge (push) Has been cancelled
react-native-android-build-apk / AssembleRelease (push) Has been cancelled
Build macOS M1 / Main (push) Has been cancelled
Joplin Continuous Integration / Main (macos-15-intel) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / Main (ubuntu-22.04-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-11-vs2026-arm) (push) Has been cancelled
Joplin Continuous Integration / Main (windows-2025) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04) (push) Has been cancelled
Joplin Continuous Integration / ServerDockerImage (ubuntu-22.04-arm) (push) Has been cancelled
Joplin UI tests / Main (ubuntu-22.04) (push) Has been cancelled
Joplin UI tests / Main (windows-2025) (push) Has been cancelled
Joplin UI tests / Mobile (push) Has been cancelled
Close stale issues / ProcessStaleIssues (push) Has been cancelled
feat: Initial clean release of CHM
2026-11-04 11:29:39 +08:00

79 行
2.7 KiB
TypeScript

// Provides spell checking feature via the native Electron built-in spell checker
import SpellCheckerServiceDriverBase from '@joplin/lib/services/spellChecker/SpellCheckerServiceDriverBase';
import bridge from '../bridge';
import Logger from '@joplin/utils/Logger';
import { languageCodeOnly, localesFromLanguageCode } from '@joplin/lib/locale';
import { Session } from 'electron';
const logger = Logger.create('SpellCheckerServiceDriverNative');
export default class SpellCheckerServiceDriverNative extends SpellCheckerServiceDriverBase {
private session(): Session {
return bridge().mainWindow().webContents.session;
}
public initialize() {
// Workaround: With Electron 42 on Linux, it's necessary to initialize the spellchecker with an empty set of
// languages. Without this, the spellchecker ignores the default provided languages.
this.setLanguages([]);
}
public get availableLanguages(): string[] {
return this.session().availableSpellCheckerLanguages;
}
// Language can be set to [] to disable spell-checking
public setLanguages(v: string[]) {
// Note that in order to validate the language we need ot set it on the
// session and check if Electron has thrown an exception or not. This is
// fine because the actual languages will be set below after the calls
// to this functions.
const validateLanguage = (v: string) => {
const languagesToTry = [
v,
languageCodeOnly(v),
].concat(localesFromLanguageCode(languageCodeOnly(v), this.availableLanguages));
for (const toTry of languagesToTry) {
try {
this.session().setSpellCheckerLanguages([toTry]);
return toTry;
} catch (error) {
logger.warn(`Failed to set language to "${toTry}". Will try the next one in this list: ${JSON.stringify(languagesToTry)}`);
logger.warn('Error was:', error);
}
}
return null;
};
const effectiveLanguages: string[] = [];
for (const language of v) {
const effectiveLanguage = validateLanguage(language);
if (effectiveLanguage) effectiveLanguages.push(effectiveLanguage);
}
// If we pass an empty array, it disables spell checking
// https://github.com/electron/electron/issues/25228
this.session().setSpellCheckerLanguages(effectiveLanguages);
this.session().setSpellCheckerEnabled(effectiveLanguages.length > 0);
logger.info(`Set effective languages to "${effectiveLanguages}"`);
}
public get language(): string {
const languages = this.session().getSpellCheckerLanguages();
return languages.length ? languages[0] : '';
}
public addWordToSpellCheckerDictionary(_language: string, word: string) {
// Actually on Electron all languages share the same dictionary, or
// perhaps it's added to the currently active language.
this.session().addWordToSpellCheckerDictionary(word);
}
}