mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-10-27 17:47:34 +09:00
parent
35d4158dd5
commit
3d983be76c
2 changed files with 118 additions and 185 deletions
|
|
@ -594,45 +594,24 @@ nsEditorSpellCheck::SetCurrentDictionary(const nsAString& aDictionary)
|
||||||
// Ignore pending dictionary fetchers by increasing this number.
|
// Ignore pending dictionary fetchers by increasing this number.
|
||||||
mDictionaryFetcherGroup++;
|
mDictionaryFetcherGroup++;
|
||||||
|
|
||||||
uint32_t flags = 0;
|
if (mPreferredLang.IsEmpty() ||
|
||||||
mEditor->GetFlags(&flags);
|
!mPreferredLang.Equals(aDictionary, nsCaseInsensitiveStringComparator())) {
|
||||||
if (!(flags & nsIPlaintextEditor::eEditorMailMask)) {
|
// When user sets dictionary manually, we store this value associated
|
||||||
if (!aDictionary.IsEmpty() && (mPreferredLang.IsEmpty() ||
|
// with editor url, if it doesn't match the document language exactly.
|
||||||
!mPreferredLang.Equals(aDictionary,
|
// For example on "en" sites, we need to store "en-GB", otherwise
|
||||||
nsCaseInsensitiveStringComparator()))) {
|
// the language might jump back to en-US although the user explicitly
|
||||||
// When user sets dictionary manually, we store this value associated
|
// chose otherwise.
|
||||||
// with editor url, if it doesn't match the document language exactly.
|
StoreCurrentDictionary(mEditor, aDictionary);
|
||||||
// For example on "en" sites, we need to store "en-GB", otherwise
|
} else {
|
||||||
// the language might jump back to en-US although the user explicitly
|
// If user sets a dictionary matching the language defined by
|
||||||
// chose otherwise.
|
// document, we consider content pref has been canceled, and we clear it.
|
||||||
StoreCurrentDictionary(mEditor, aDictionary);
|
ClearCurrentDictionary(mEditor);
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Writing content preferences for |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(aDictionary).get());
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
// If user sets a dictionary matching the language defined by
|
|
||||||
// document, we consider content pref has been canceled, and we clear it.
|
|
||||||
ClearCurrentDictionary(mEditor);
|
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Clearing content preferences for |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(aDictionary).get());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also store it in as a preference, so we can use it as a fallback.
|
|
||||||
// We don't want this for mail composer because it uses
|
|
||||||
// "spellchecker.dictionary" as a preference.
|
|
||||||
Preferences::SetString("spellchecker.dictionary", aDictionary);
|
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Storing spellchecker.dictionary |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(aDictionary).get());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mSpellChecker->SetCurrentDictionary(aDictionary);
|
return mSpellChecker->SetCurrentDictionary(aDictionary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsEditorSpellCheck::UninitSpellChecker()
|
nsEditorSpellCheck::UninitSpellChecker()
|
||||||
{
|
{
|
||||||
|
|
@ -771,23 +750,16 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We try to derive the dictionary to use based on the following priorities:
|
* We try to derive the dictionary to use based on the following priorities:
|
||||||
* 1) Content preference, so the language the user set for the site before.
|
* 1) Content preference: the language the user set for the site before.
|
||||||
* (Introduced in bug 678842 and corrected in bug 717433.)
|
* 2) The value of "spellchecker.dictionary.override" which reflects a
|
||||||
* 2) Language set by the website, or any other dictionary that partly
|
* global choice of language explicitly set by the user.
|
||||||
* matches that. (Introduced in bug 338427.)
|
* 3) Language set by the website, or any other dictionary that partly matches that.
|
||||||
* Eg. if the website is "en-GB", a user who only has "en-US" will get
|
* Eg. if the website is "en-GB", a user who only has "en-US" will get that.
|
||||||
* that. If the website is generic "en", the user will get one of the
|
* If the website is generic "en", the user will get one of the "en-*" installed,
|
||||||
* "en-*" installed, (almost) at random.
|
* pretty much at random.
|
||||||
* However, we prefer what is stored in "spellchecker.dictionary",
|
* 4) The user's locale
|
||||||
* so if the user chose "en-AU" before, they will get "en-AU" on a plain
|
* 5) Leave the current dictionary set.
|
||||||
* "en" site. (Introduced in bug 682564.)
|
* 6) The content of the "LANG" environment variable (if set)
|
||||||
* 3) The value of "spellchecker.dictionary" which reflects a previous
|
|
||||||
* language choice of the user (on another site).
|
|
||||||
* (This was the original behaviour before the aforementioned bugs
|
|
||||||
* landed).
|
|
||||||
* 4) The user's locale.
|
|
||||||
* 5) Use the current dictionary that is currently set.
|
|
||||||
* 6) The content of the "LANG" environment variable (if set).
|
|
||||||
* 7) The first spell check dictionary installed.
|
* 7) The first spell check dictionary installed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -795,84 +767,74 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
|
||||||
// https://html.spec.whatwg.org/#attr-lang
|
// https://html.spec.whatwg.org/#attr-lang
|
||||||
// This is used in SetCurrentDictionary.
|
// This is used in SetCurrentDictionary.
|
||||||
mPreferredLang.Assign(aFetcher->mRootContentLang);
|
mPreferredLang.Assign(aFetcher->mRootContentLang);
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** mPreferredLang (element) |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(mPreferredLang).get());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// If no luck, try the "Content-Language" header.
|
// If no luck, try the "Content-Language" header.
|
||||||
if (mPreferredLang.IsEmpty()) {
|
if (mPreferredLang.IsEmpty()) {
|
||||||
mPreferredLang.Assign(aFetcher->mRootDocContentLang);
|
mPreferredLang.Assign(aFetcher->mRootDocContentLang);
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** mPreferredLang (content-language) |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(mPreferredLang).get());
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Auxiliary status.
|
|
||||||
nsresult rv2;
|
|
||||||
|
|
||||||
// We obtain a list of available dictionaries.
|
|
||||||
nsTArray<nsString> dictList;
|
|
||||||
rv2 = mSpellChecker->GetDictionaryList(&dictList);
|
|
||||||
NS_ENSURE_SUCCESS(rv2, rv2);
|
|
||||||
|
|
||||||
// Priority 1:
|
// Priority 1:
|
||||||
|
// Get language from content prefs, if set.
|
||||||
// If we successfully fetched a dictionary from content prefs, do not go
|
// If we successfully fetched a dictionary from content prefs, do not go
|
||||||
// further. Use this exact dictionary.
|
// further. Use this exact dictionary.
|
||||||
// Don't use content preferences for editor with eEditorMailMask flag.
|
|
||||||
nsAutoString dictName;
|
nsAutoString dictName;
|
||||||
uint32_t flags;
|
dictName.Assign(aFetcher->mDictionary);
|
||||||
mEditor->GetFlags(&flags);
|
if (!dictName.IsEmpty()) {
|
||||||
if (!(flags & nsIPlaintextEditor::eEditorMailMask)) {
|
if (NS_SUCCEEDED(SetCurrentDictionary(dictName))) {
|
||||||
dictName.Assign(aFetcher->mDictionary);
|
// We take an early exit here, so clear the suggested word list.
|
||||||
if (!dictName.IsEmpty()) {
|
DeleteSuggestedWordList();
|
||||||
if (NS_SUCCEEDED(TryDictionary(dictName, dictList, DICT_NORMAL_COMPARE))) {
|
return NS_OK;
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Assigned from content preferences |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(dictName).get());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// We take an early exit here, so let's not forget to clear the word
|
|
||||||
// list.
|
|
||||||
DeleteSuggestedWordList();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
// May be dictionary was uninstalled ?
|
|
||||||
// Clear the content preference and continue.
|
|
||||||
ClearCurrentDictionary(mEditor);
|
|
||||||
}
|
}
|
||||||
|
// Maybe the dictionary was uninstalled ?
|
||||||
|
// Clear the content preference and continue.
|
||||||
|
ClearCurrentDictionary(mEditor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 2:
|
// Priority 2:
|
||||||
// After checking the content preferences, we use the language of the element
|
// Get global preferred language from preferences, if set.
|
||||||
// or document.
|
|
||||||
dictName.Assign(mPreferredLang);
|
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Assigned from element/doc |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(dictName).get());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get the preference value.
|
|
||||||
nsAutoString preferredDict;
|
nsAutoString preferredDict;
|
||||||
preferredDict = Preferences::GetLocalizedString("spellchecker.dictionary");
|
preferredDict = Preferences::GetLocalizedString("spellchecker.dictionary.override");
|
||||||
|
if (!preferredDict.IsEmpty()) {
|
||||||
|
dictName.Assign(preferredDict);
|
||||||
|
}
|
||||||
|
|
||||||
// The following will be driven by this status. Once we were able to set a
|
// Priority 3:
|
||||||
|
// Get language from element/doc, if set.
|
||||||
|
if (dictName.IsEmpty() && !mPreferredLang.IsEmpty()) {
|
||||||
|
dictName.Assign(mPreferredLang);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auxiliary status value
|
||||||
|
nsresult rv2;
|
||||||
|
|
||||||
|
// Obtain a list of available dictionaries to check against.
|
||||||
|
nsTArray<nsString> dictList;
|
||||||
|
rv2 = mSpellChecker->GetDictionaryList(&dictList);
|
||||||
|
NS_ENSURE_SUCCESS(rv2, rv2);
|
||||||
|
int32_t i, dictCount = dictList.Length();
|
||||||
|
|
||||||
|
// The following will be driven by this status. Once we are able to set a
|
||||||
// dictionary successfully, we're done. So we start with a "failed" status.
|
// dictionary successfully, we're done. So we start with a "failed" status.
|
||||||
nsresult rv = NS_ERROR_NOT_AVAILABLE;
|
nsresult rv = NS_ERROR_FAILURE;
|
||||||
|
|
||||||
if (!dictName.IsEmpty()) {
|
if (!dictName.IsEmpty()) {
|
||||||
// RFC 5646 explicitly states that matches should be case-insensitive.
|
for (i = 0; i < dictCount; i++) {
|
||||||
rv = TryDictionary (dictName, dictList, DICT_COMPARE_CASE_INSENSITIVE);
|
nsAutoString dictStr(dictList.ElementAt(i));
|
||||||
|
if (dictName.Equals(dictStr, nsCaseInsensitiveStringComparator())) {
|
||||||
|
// First let's correct any problems due to non-matching case.
|
||||||
|
// This applies to both a user-set override and document language.
|
||||||
|
// RFC 5646 explicitly states that matches should be case-insensitive.
|
||||||
|
dictName.Assign(dictStr);
|
||||||
|
// Try to set it. Doing this inside this loop avoids trying to set a
|
||||||
|
// dictionary that isn't available.
|
||||||
|
rv = SetCurrentDictionary(dictName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Setting of |%s| failed (or it wasn't available)\n",
|
|
||||||
NS_ConvertUTF16toUTF8(dictName).get());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Required dictionary was not available. Try to get a dictionary
|
// Required dictionary was not available. Try to get a dictionary
|
||||||
// matching at least language part of dictName.
|
// matching at least the language part of dictName:
|
||||||
nsAutoString langCode;
|
nsAutoString langCode;
|
||||||
int32_t dashIdx = dictName.FindChar('-');
|
int32_t dashIdx = dictName.FindChar('-');
|
||||||
if (dashIdx != -1) {
|
if (dashIdx != -1) {
|
||||||
|
|
@ -881,45 +843,24 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
|
||||||
langCode.Assign(dictName);
|
langCode.Assign(dictName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try dictionary.spellchecker preference, if it starts with langCode,
|
nsDefaultStringComparator comparator;
|
||||||
// so we don't just get any random dictionary matching the language.
|
|
||||||
if (!preferredDict.IsEmpty() &&
|
|
||||||
nsStyleUtil::DashMatchCompare(preferredDict, langCode, nsDefaultStringComparator())) {
|
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Trying preference value |%s| since it matches language code\n",
|
|
||||||
NS_ConvertUTF16toUTF8(preferredDict).get());
|
|
||||||
#endif
|
|
||||||
rv = TryDictionary (preferredDict, dictList,
|
|
||||||
DICT_COMPARE_CASE_INSENSITIVE);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
// Loop over available dictionaries; if we find one with the required
|
||||||
// Use any dictionary with the required language.
|
// language, use it.
|
||||||
#ifdef DEBUG_DICT
|
for (i = 0; i < dictCount; i++) {
|
||||||
printf("***** Trying to find match for language code |%s|\n",
|
nsAutoString dictStr(dictList.ElementAt(i));
|
||||||
NS_ConvertUTF16toUTF8(langCode).get());
|
if (nsStyleUtil::DashMatchCompare(dictStr, langCode, comparator) &&
|
||||||
#endif
|
NS_SUCCEEDED(rv = SetCurrentDictionary(dictStr))) {
|
||||||
rv = TryDictionary (langCode, dictList, DICT_COMPARE_DASHMATCH);
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 3:
|
|
||||||
// If the document didn't supply a dictionary or the setting failed,
|
|
||||||
// try the user preference next.
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
if (!preferredDict.IsEmpty()) {
|
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Trying preference value |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(preferredDict).get());
|
|
||||||
#endif
|
|
||||||
rv = TryDictionary (preferredDict, dictList, DICT_NORMAL_COMPARE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Priority 4:
|
// Priority 4:
|
||||||
// As next fallback, try the current locale.
|
// Content prefs, override and document didn't give us a valid dictionary
|
||||||
if (NS_FAILED(rv)) {
|
// name, so we just get the current locale and try to use that.
|
||||||
|
if (NS_FAILED (rv)) {
|
||||||
nsCOMPtr<nsIXULChromeRegistry> packageRegistry =
|
nsCOMPtr<nsIXULChromeRegistry> packageRegistry =
|
||||||
mozilla::services::GetXULChromeRegistryService();
|
mozilla::services::GetXULChromeRegistryService();
|
||||||
|
|
||||||
|
|
@ -929,67 +870,55 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
|
||||||
false, utf8DictName);
|
false, utf8DictName);
|
||||||
dictName.Assign(EmptyString());
|
dictName.Assign(EmptyString());
|
||||||
AppendUTF8toUTF16(utf8DictName, dictName);
|
AppendUTF8toUTF16(utf8DictName, dictName);
|
||||||
#ifdef DEBUG_DICT
|
// Try to set it, if it's in the list.
|
||||||
printf("***** Trying locale |%s|\n",
|
for (i = 0; i < dictCount; i++) {
|
||||||
NS_ConvertUTF16toUTF8(dictName).get());
|
nsAutoString dictStr(dictList.ElementAt(i));
|
||||||
#endif
|
if (dictStr.Equals(dictName)) {
|
||||||
rv = TryDictionary (dictName, dictList, DICT_COMPARE_CASE_INSENSITIVE);
|
rv = SetCurrentDictionary(dictName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
// Still no success.
|
// Still no success. Further fallback attempts required.
|
||||||
|
|
||||||
// Priority 5:
|
// Priority 5:
|
||||||
// If we have a current dictionary, don't try anything else.
|
// If we have a current dictionary, don't try anything else.
|
||||||
nsAutoString currentDictionary;
|
nsAutoString currentDictionary;
|
||||||
rv2 = GetCurrentDictionary(currentDictionary);
|
rv2 = GetCurrentDictionary(currentDictionary);
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
if (NS_SUCCEEDED(rv2)) {
|
|
||||||
printf("***** Retrieved current dict |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(currentDictionary).get());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (NS_FAILED(rv2) || currentDictionary.IsEmpty()) {
|
if (NS_FAILED(rv2) || currentDictionary.IsEmpty()) {
|
||||||
|
// We don't have a current dictionary.
|
||||||
// Priority 6:
|
// Priority 6:
|
||||||
// Try to get current dictionary from environment variable LANG.
|
// Try to get current dictionary from environment variable LANG.
|
||||||
// LANG = language[_territory][.charset]
|
// LANG = language[_territory][.codeset]
|
||||||
char* env_lang = getenv("LANG");
|
char* env_lang = getenv("LANG");
|
||||||
if (env_lang) {
|
if (env_lang != nullptr) {
|
||||||
nsString lang = NS_ConvertUTF8toUTF16(env_lang);
|
nsString lang = NS_ConvertUTF8toUTF16(env_lang);
|
||||||
|
|
||||||
// Strip trailing charset, if there is any.
|
// Strip trailing charset, if there is any.
|
||||||
int32_t dot_pos = lang.FindChar('.');
|
int32_t dot_pos = lang.FindChar('.');
|
||||||
if (dot_pos != -1) {
|
if (dot_pos != -1) {
|
||||||
lang = Substring(lang, 0, dot_pos);
|
lang = Substring(lang, 0, dot_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Convert underscore to dash.
|
||||||
int32_t underScore = lang.FindChar('_');
|
int32_t underScore = lang.FindChar('_');
|
||||||
if (underScore != -1) {
|
if (underScore != -1) {
|
||||||
lang.Replace(underScore, 1, '-');
|
lang.Replace(underScore, 1, '-');
|
||||||
#ifdef DEBUG_DICT
|
// Only attempt to set if a _territory is present.
|
||||||
printf("***** Trying LANG from environment |%s|\n",
|
rv = SetCurrentDictionary(lang);
|
||||||
NS_ConvertUTF16toUTF8(lang).get());
|
|
||||||
#endif
|
|
||||||
nsAutoString lang2;
|
|
||||||
lang2.Assign(lang);
|
|
||||||
rv = TryDictionary(lang2, dictList, DICT_COMPARE_CASE_INSENSITIVE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Priority 7:
|
// Priority 7:
|
||||||
// If it does not work, pick the first one.
|
// If LANG does not work either, pick the first one.
|
||||||
if (NS_FAILED(rv) && !dictList.IsEmpty()) {
|
if (NS_FAILED(rv)) {
|
||||||
nsAutoString firstInList;
|
if (dictList.Length() > 0) {
|
||||||
firstInList.Assign(dictList[0]);
|
rv = SetCurrentDictionary(dictList[0]);
|
||||||
rv = TryDictionary(firstInList, dictList, DICT_NORMAL_COMPARE);
|
|
||||||
#ifdef DEBUG_DICT
|
|
||||||
printf("***** Trying first of list |%s|\n",
|
|
||||||
NS_ConvertUTF16toUTF8(dictList[0]).get());
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
printf ("***** Setting worked.\n");
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -999,6 +928,7 @@ nsEditorSpellCheck::DictionaryFetched(DictionaryFetcher* aFetcher)
|
||||||
// up. The user can manually reset the language to their choice on
|
// up. The user can manually reset the language to their choice on
|
||||||
// the dialog if it is wrong.
|
// the dialog if it is wrong.
|
||||||
|
|
||||||
|
// Dictionary has changed, so delete the suggested word list.
|
||||||
DeleteSuggestedWordList();
|
DeleteSuggestedWordList();
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
|
|
||||||
|
|
@ -1117,6 +1117,9 @@ pref("print.print_via_parent", false);
|
||||||
// in a document.
|
// in a document.
|
||||||
pref("extensions.spellcheck.inline.max-misspellings", 500);
|
pref("extensions.spellcheck.inline.max-misspellings", 500);
|
||||||
|
|
||||||
|
// Predefined convenience pref for overriding the dictionary
|
||||||
|
pref("spellchecker.dictionary.override", "");
|
||||||
|
|
||||||
// Prefs used by libeditor. Prefs specific to seamonkey composer
|
// Prefs used by libeditor. Prefs specific to seamonkey composer
|
||||||
// belong in comm-central/editor/ui/composer.js
|
// belong in comm-central/editor/ui/composer.js
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue