Bug 1761273 - Check for multiple dictionaries when saving site preferences; r=smaug

We only want to save the site preferences when the user's dictionary
preferences do not match the preferred language for the site. This is always
the case when there is more than one dictionary in use, but the current
code does not handle this case.

Differential Revision: https://phabricator.services.mozilla.com/D141981
This commit is contained in:
Dan Minor 2022-03-24 22:29:42 +00:00
parent c4d7e79183
commit 64d31d44db
5 changed files with 123 additions and 7 deletions

View File

@ -2,11 +2,19 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var EXPORTED_SYMBOLS = ["maybeOnSpellCheck", "onSpellCheck"];
var EXPORTED_SYMBOLS = [
"maybeOnSpellCheck",
"onSpellCheck",
"getDictionaryContentPref",
];
const SPELL_CHECK_ENDED_TOPIC = "inlineSpellChecker-spellCheck-ended";
const SPELL_CHECK_STARTED_TOPIC = "inlineSpellChecker-spellCheck-started";
const CP = Cc["@mozilla.org/content-pref/service;1"].getService(
Ci.nsIContentPrefService2
);
/**
* Waits until spell checking has stopped on the given element.
*
@ -105,3 +113,19 @@ function onSpellCheck(editableElement, callback) {
callback
);
}
async function getDictionaryContentPref() {
let dictionaries = await new Promise(resolve => {
let value = "";
CP.getByDomainAndName("mochi.test", "spellcheck.lang", null, {
handleResult(pref) {
value = pref.value;
},
handleCompletion() {
resolve(value);
},
});
});
return dictionaries;
}

View File

@ -603,10 +603,9 @@ EditorSpellCheck::SetCurrentDictionaries(
mEditor->GetFlags(&flags);
if (!(flags & nsIEditor::eEditorMailMask)) {
if (!aDictionaries.IsEmpty() &&
(mPreferredLang.IsEmpty() ||
(aDictionaries.Length() == 1 &&
!mPreferredLang.Equals(aDictionaries[0],
nsCaseInsensitiveCStringComparator)))) {
(mPreferredLang.IsEmpty() || aDictionaries.Length() > 1 ||
!mPreferredLang.Equals(aDictionaries[0],
nsCaseInsensitiveCStringComparator))) {
// When user sets dictionary manually, we store this value associated
// with editor url, if it doesn't match the document language exactly.
// For example on "en" sites, we need to store "en-GB", otherwise

View File

@ -41,6 +41,7 @@ skip-if = e10s
[test_bug1418629.html]
[test_bug1497480.html]
[test_bug1602526.html]
[test_bug1761273.html]
[test_spellcheck_after_edit.html]
[test_spellcheck_after_pressing_navigation_key.html]
[test_suggest.html]

View File

@ -4,13 +4,13 @@
https://bugzilla.mozilla.org/show_bug.cgi?id=1402822
-->
<head>
<title>Test for Bug 1209414</title>
<title>Test for Bug 1402822</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1209414">Mozilla Bug 1209414</a>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1402822">Mozilla Bug 1402822</a>
<p id="display"></p>
</div>

View File

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=1761273
-->
<head>
<title>Test for Bug 1761273</title>
<script src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1761273">Mozilla Bug 1761273</a>
<p id="display"></p>
</div>
<textarea id="editor" lang="en-US">heute ist ein guter Tag - today is a good day</textarea>
<pre id="test">
<script class="testbody" type="text/javascript">
const Ci = SpecialPowers.Ci;
let {getDictionaryContentPref, onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
/** Test for Bug 1402822 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(start);
async function start() {
/* global actorParent */
/* eslint-env mozilla/frame-script */
let script = SpecialPowers.loadChromeScript(() => {
// eslint-disable-next-line mozilla/use-services
let dir = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
.get("CurWorkD", Ci.nsIFile);
dir.append("tests");
dir.append("editor");
dir.append("spellchecker");
dir.append("tests");
let hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
.getService(Ci.mozISpellCheckingEngine);
// Install de-DE dictionary.
let de_DE = dir.clone();
de_DE.append("de-DE");
hunspell.addDirectory(de_DE);
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
addMessageListener("de_DE-exists", () => de_DE.exists());
});
is(await script.sendQuery("de_DE-exists"), true,
"true expected (de_DE directory should exist)");
let textarea = document.getElementById("editor");
textarea.focus();
onSpellCheck(textarea, async () => {
let isc = SpecialPowers.wrap(textarea).editor.getInlineSpellChecker(true);
ok(isc, "Inline spell checker should exist after focus and spell check");
let spellchecker = isc.spellChecker;
// Setting the language to the language of the texteditor should not set the
// content preference.
await spellchecker.setCurrentDictionaries(["en-US"]);
let dictionaryContentPref = await getDictionaryContentPref();
is(dictionaryContentPref, "", "Content pref should be empty");
await spellchecker.setCurrentDictionaries(["en-US", "de-DE"]);
dictionaryContentPref = await getDictionaryContentPref();
is(dictionaryContentPref, "en-US,de-DE,", "Content pref should be en-US,de-DE,");
await spellchecker.setCurrentDictionaries(["de-DE"]);
dictionaryContentPref = await getDictionaryContentPref();
is(dictionaryContentPref, "de-DE,", "Content pref should be de-DE,");
// Remove the fake de_DE dictionary again.
await script.sendQuery("destroy");
// This will clear the content preferences and reset "spellchecker.dictionary".
await spellchecker.setCurrentDictionaries([]);
dictionaryContentPref = await getDictionaryContentPref();
is(dictionaryContentPref, "", "Content pref should be empty");
SimpleTest.finish();
});
}
</script>
</pre>
</body>
</html>