NS_IMPL_COMPONENT_FACTORY(mozHunspell) { auto hunspell = MakeRefPtr<mozHunspell>(); if (NS_SUCCEEDED(hunspell->Init())) { return hunspell.forget().downcast<mozISpellCheckingEngine>();
} return nullptr;
}
mozHunspell::mozHunspell() { #ifdef DEBUG // There must be only one instance of this class: it reports memory based on // a single static count in HunspellAllocator. staticbool hasRun = false;
MOZ_ASSERT(!hasRun);
hasRun = true; #endif
}
NS_IMETHODIMP
mozHunspell::GetDictionaries(nsTArray<nsCString>& aDictionaries) {
MOZ_ASSERT(aDictionaries.IsEmpty()); for (auto iter = mHunspells.ConstIter(); !iter.Done(); iter.Next()) { if (iter.Data().mEnabled) {
aDictionaries.AppendElement(iter.Key());
}
} return NS_OK;
}
/* Set the Dictionaries. *ThisalsoLoadsthedictionariesandinitializestheconverterusingthe *dictionariesconverter
*/
NS_IMETHODIMP
mozHunspell::SetDictionaries(const nsTArray<nsCString>& aDictionaries) { if (aDictionaries.IsEmpty()) {
mHunspells.Clear(); return NS_OK;
}
// Disable any dictionaries we've already loaded that we're not // going to use. for (auto iter = mHunspells.Iter(); !iter.Done(); iter.Next()) { if (!aDictionaries.Contains(iter.Key())) {
iter.Data().mEnabled = false;
}
}
// If we have a large number of dictionaries loaded, try freeing any disabled // dictionaries to limit memory use. if (mHunspells.Count() > 10) {
mHunspells.RemoveIf([](constauto& iter) { return !iter.Data().mEnabled; });
}
// find built in dictionaries, or dictionaries specified in // spellchecker.dictionary_path in prefs
nsCOMPtr<nsIFile> dictDir;
// check preferences first
nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); if (prefs) {
nsAutoCString extDictPath;
rv = prefs->GetCharPref("spellchecker.dictionary_path", extDictPath); if (NS_SUCCEEDED(rv)) { // set the spellchecker.dictionary_path
rv = NS_NewNativeLocalFile(extDictPath, getter_AddRefs(dictDir));
} if (dictDir) {
LoadDictionariesFromDir(dictDir);
}
}
// find dictionaries in DICPATH char* dicEnv = PR_GetEnv("DICPATH"); if (dicEnv) { // do a two-pass dance so dictionaries are loaded right-to-left as // preference
nsTArray<nsCOMPtr<nsIFile>> dirs;
nsAutoCString env(dicEnv); // assume dicEnv is UTF-8
// load them in reverse order so they override each other properly for (int32_t i = dirs.Length() - 1; i >= 0; i--) {
LoadDictionariesFromDir(dirs[i]);
}
}
// find dictionaries from restartless extensions for (int32_t i = 0; i < mDynamicDirectories.Count(); i++) {
LoadDictionariesFromDir(mDynamicDirectories[i]);
}
for (constauto& dictionaryEntry : mDynamicDictionaries) {
mDictionaries.InsertOrUpdate(dictionaryEntry.GetKey(),
dictionaryEntry.GetData());
}
DictionariesChanged(aNotifyChildProcesses);
}
void mozHunspell::DictionariesChanged(bool aNotifyChildProcesses) { // Now we have finished updating the list of dictionaries, update the current // dictionary and any editors which may use it.
mozInlineSpellChecker::UpdateCanEnableInlineSpellChecking();
if (aNotifyChildProcesses) {
mozilla::dom::ContentParent_NotifyUpdatedDictionaries();
}
// Check if the current dictionaries are still available. // If not, try to replace it with other dictionaries of the same language. if (!mHunspells.IsEmpty()) {
nsTArray<nsCString> dictionaries; for (auto iter = mHunspells.ConstIter(); !iter.Done(); iter.Next()) { if (iter.Data().mEnabled) {
dictionaries.AppendElement(iter.Key());
}
}
nsresult rv = SetDictionaries(dictionaries); if (NS_SUCCEEDED(rv)) return;
}
// If the current dictionaries are gone, and we don't have a good replacement, // set no current dictionary. if (!mHunspells.IsEmpty()) {
nsTArray<nsCString> empty;
SetDictionaries(empty);
}
}
rv = aDir->IsDirectory(&check); if (NS_FAILED(rv) || !check) return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIDirectoryEnumerator> files;
rv = aDir->GetDirectoryEntries(getter_AddRefs(files)); if (NS_FAILED(rv)) return NS_ERROR_UNEXPECTED;
nsCOMPtr<nsIFile> file; while (NS_SUCCEEDED(files->GetNextFile(getter_AddRefs(file))) && file) {
nsAutoString leafName;
file->GetLeafName(leafName); if (!StringEndsWith(leafName, u".dic"_ns)) continue;
nsAutoString dict(leafName);
dict.SetLength(dict.Length() - 4); // magic length of ".dic"
// check for the presence of the .aff file
leafName = dict;
leafName.AppendLiteral(".aff");
file->SetLeafName(leafName);
rv = file->Exists(&check); if (NS_FAILED(rv) || !check) continue;
// Replace '_' separator with '-'
dict.ReplaceChar('_', '-');
// Depending upon the encoding, we might end up with a string that begins // with the null byte. Since the hunspell interface uses C-style strings, // this appears like an empty string, and hunspell marks empty strings as // spelled correctly. Skip these cases to allow another dictionary to have // the chance to spellcheck them. if (charsetWord.empty() || charsetWord[0] == 0) { continue;
}
*aResult = iter.Data().mHunspell->spell(charsetWord); if (*aResult) { break;
}
}
if (!*aResult && mPersonalDictionary) { return mPersonalDictionary->Check(aWord, aResult);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.