Bug 1402822 - Update unit tests for multiple dictionaries; r=smaug

For the most part these are simple updates to account for multiple
dictionaries and the fact that SetDictionaries is async whereas
SetDictionary was sync.

Fixing test_async_UpdateCurrentDictionary was more involved because
there were flaws in the existing test and it is more difficult to
harmonize the UpdateCurrentDictionary callback with the changes to make
SetDictionaries async.

Differential Revision: https://phabricator.services.mozilla.com/D140245
This commit is contained in:
Dan Minor 2022-03-23 13:53:39 +00:00
parent c6e75d499a
commit 337bc15035
37 changed files with 234 additions and 229 deletions

View File

@ -2,7 +2,7 @@
* 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 = ["onSpellCheck"];
var EXPORTED_SYMBOLS = ["maybeOnSpellCheck", "onSpellCheck"];
const SPELL_CHECK_ENDED_TOPIC = "inlineSpellChecker-spellCheck-ended";
const SPELL_CHECK_STARTED_TOPIC = "inlineSpellChecker-spellCheck-started";
@ -24,7 +24,7 @@ const SPELL_CHECK_STARTED_TOPIC = "inlineSpellChecker-spellCheck-started";
* of the event loop have passed to determine it has not
* started.
*/
function onSpellCheck(editableElement, callback) {
function maybeOnSpellCheck(editableElement, callback) {
let editor = editableElement.editor;
if (!editor) {
let win = editableElement.ownerGlobal;
@ -72,9 +72,9 @@ function onSpellCheck(editableElement, callback) {
let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.init(
function tick() {
// Wait an arbitrarily large number -- 50 -- turns of the event loop before
// Wait an arbitrarily large number -- 100 -- turns of the event loop before
// declaring that no spell checks will start.
if (waitingForEnded || ++count < 50) {
if (waitingForEnded || ++count < 100) {
return;
}
timer.cancel();
@ -86,3 +86,22 @@ function onSpellCheck(editableElement, callback) {
Ci.nsITimer.TYPE_REPEATING_SLACK
);
}
/**
* Waits until spell checking has stopped on the given element.
*
* @param editableElement The element being spell checked.
* @param callback Called when spell check has completed or enough turns
* of the event loop have passed to determine it has not
* started.
*/
function onSpellCheck(editableElement, callback) {
const { TestUtils } = ChromeUtils.import(
"resource://testing-common/TestUtils.jsm"
);
let editor = editableElement.editor;
TestUtils.topicObserved(SPELL_CHECK_ENDED_TOPIC, s => s == editor).then(
callback
);
}

View File

@ -8,7 +8,7 @@ function load()
textarea.focus();
SpecialPowers.Cu.import("resource://reftest/AsyncSpellCheckTestHelper.jsm")
.onSpellCheck(textarea, () => {
.maybeOnSpellCheck(textarea, () => {
let isc = SpecialPowers.wrap(textarea).editor.getInlineSpellChecker(false);
let sc = isc.spellChecker;

View File

@ -95,7 +95,7 @@ SimpleTest.waitForFocus(async () => {
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
.onSpellCheck(aElement, () => {
.maybeOnSpellCheck(aElement, () => {
SimpleTest.executeSoon(() => {
aElement.addEventListener("beforeinput", onBeforeInput);
aElement.addEventListener("input", onInput);

View File

@ -30,44 +30,29 @@ function start() {
var isc = SpecialPowers.wrap(textarea).editor.getInlineSpellChecker(false);
ok(isc, "Inline spell checker should exist after focus and spell check");
var sc = isc.spellChecker;
isnot(sc.GetCurrentDictionary(), lang,
"Current dictionary should not be set yet.");
// First, set the lang attribute on the textarea, call Update, and make
// sure the spell checker's language was updated appropriately.
var lang = "en-US";
textarea.setAttribute("lang", lang);
sc.UpdateCurrentDictionary(function() {
is(sc.GetCurrentDictionary(), lang,
"UpdateCurrentDictionary should set the current dictionary.");
sc.setCurrentDictionaries(["testing-XX"]).then(() => {
is(true, false, "Setting a non-existent dictionary should fail");
}, () => {
let currentDictionaries = sc.getCurrentDictionaries();
// Second, make some Update calls, but then do a Set. The Set should
// effectively cancel the Updates, but the Updates' callbacks should be
// called nonetheless.
var numCalls = 3;
for (var i = 0; i < numCalls; i++) {
sc.UpdateCurrentDictionary(function() {
is(sc.GetCurrentDictionary(), "",
"No dictionary should be active after Update.");
if (--numCalls == 0) {
// This will clear the content preferences and reset "spellchecker.dictionary".
sc.SetCurrentDictionary("");
SimpleTest.finish();
}
is(currentDictionaries.length, 0, "expected no dictionaries");
// First, set the lang attribute on the textarea, call Update, and make
// sure the spell checker's language was updated appropriately.
var lang = "en-US";
textarea.setAttribute("lang", lang);
sc.UpdateCurrentDictionary(function() {
currentDictionaries = sc.getCurrentDictionaries();
is(currentDictionaries.length, 1, "expected one dictionary");
is(sc.getCurrentDictionaries()[0], lang,
"UpdateCurrentDictionary should set the current dictionary.");
sc.setCurrentDictionaries([]).then(() => {
SimpleTest.finish();
});
}
try {
sc.SetCurrentDictionary("testing-XX");
} catch (err) {
// Set throws NS_ERROR_NOT_AVAILABLE because "testing-XX" isn't really
// an available dictionary.
}
is(sc.GetCurrentDictionary(), "",
"No dictionary should be active after Set.");
});
});
});
}
</script>
</pre>
</body>

View File

@ -23,7 +23,7 @@ fivee sixx<br>
<script class="testbody" type="application/javascript">
let {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
let {maybeOnSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
/** Test for Bug 1100966 **/
SimpleTest.waitForExplicitFinish();
@ -39,7 +39,7 @@ SimpleTest.waitForFocus(function() {
SimpleTest.executeSoon(function() {
synthesizeKey("KEY_Backspace");
onSpellCheck(div, function() {
maybeOnSpellCheck(div, function() {
var sel = getSpellCheckSelection();
is(sel.rangeCount, 2, "We should have two misspelled words");
is(String(sel.getRangeAt(0)), "fivee", "Correct misspelled word");

View File

@ -22,7 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1154791
<script class="testbody" type="application/javascript">
let {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
let {maybeOnSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
/** Test for Bug 1154791 **/
SimpleTest.waitForExplicitFinish();
@ -39,7 +39,7 @@ SimpleTest.waitForFocus(function() {
SimpleTest.executeSoon(function() {
sendString(" ");
onSpellCheck(div, function() {
maybeOnSpellCheck(div, function() {
var sel = getSpellCheckSelection();
is(sel.rangeCount, 2, "We should have two misspelled words");
is(String(sel.getRangeAt(0)), "thiss", "Correct misspelled word");

View File

@ -108,13 +108,14 @@ function continueTest(evt) {
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
.onSpellCheck(elem, function() {
.onSpellCheck(elem, async function() {
var spellchecker = inlineSpellChecker.spellChecker;
let currentDictionaries;
try {
var dict = spellchecker.GetCurrentDictionary();
currentDictionaries = spellchecker.getCurrentDictionaries();
} catch (e) {}
if (!dict && !retrying) {
if (!currentDictionaries && !retrying) {
// It's possible for an asynchronous font-list update to cause a reflow
// that disrupts the async spell-check and results in not getting a
// current dictionary here; if that happens, we retry the same testcase
@ -122,6 +123,8 @@ function continueTest(evt) {
info(`No current dictionary: retrying testcase ${loadCount}`);
retrying = true;
} else {
is(currentDictionaries.length, 1, "expected one dictionary");
let dict = currentDictionaries[0];
if (tests[loadCount][2] != "*") {
is(dict, tests[loadCount][2], "expected " + tests[loadCount][2]);
} else if (is_en_US && tests[loadCount][0].startsWith("en")) {
@ -142,7 +145,7 @@ function continueTest(evt) {
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1200533_subframe.html?firstload=false";
} else {
// Remove the fake dictionaries again, since it's otherwise picked up by later tests.
script.sendAsyncMessage("destroy");
await script.sendQuery("destroy");
SimpleTest.finish();
}

View File

@ -71,17 +71,16 @@ var loadListener = async function(evt) {
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
.onSpellCheck(elem, function() {
var spellchecker = inlineSpellChecker.spellChecker;
try {
var currentDictonary = spellchecker.GetCurrentDictionary();
} catch (e) {}
.onSpellCheck(elem, async function() {
let spellchecker = inlineSpellChecker.spellChecker;
let currentDictionaries = spellchecker.getCurrentDictionaries();
is(currentDictionaries.length, 1, "expected one dictionary");
let currentDictionary = currentDictionaries[0];
if (firstLoad) {
firstLoad = false;
// First time around, the element's language should be used.
is(currentDictonary, "en-GB", "unexpected lang " + currentDictonary + " instead of en-GB");
is(currentDictionary, "en-GB", "unexpected lang " + currentDictionary + " instead of en-GB");
// Note that on second load, we load a different page, which does NOT have the trouble-causing
// contenteditable in it. Sadly, loading the same page with the trouble-maker in it
@ -93,11 +92,11 @@ var loadListener = async function(evt) {
} else {
// Second time around, the element should default to en-US.
// Without the fix, the first run sets the content preference to en-GB for the whole site.
is(currentDictonary, "en-US", "unexpected lang " + currentDictonary + " instead of en-US");
is(currentDictionary, "en-US", "unexpected lang " + currentDictionary + " instead of en-US");
content.removeEventListener("load", loadListener);
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
script.sendAsyncMessage("destroy");
await script.sendQuery("destroy");
// Reset the preference, so the last value we set doesn't collide with the next test.
SimpleTest.finish();

View File

@ -28,9 +28,9 @@ var editor_de;
var selcon_de;
var script;
var onSpellCheck =
var maybeOnSpellCheck =
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck;
"resource://testing-common/AsyncSpellCheckTestHelper.jsm").maybeOnSpellCheck;
/** Test for Bug 1205983 **/
SimpleTest.waitForExplicitFinish();
@ -66,7 +66,7 @@ SimpleTest.waitForFocus(async function() {
function deFocus() {
elem_de = document.getElementById("de-DE");
onSpellCheck(elem_de, function() {
maybeOnSpellCheck(elem_de, function() {
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
editor_de = editingSession.getEditorForWindow(window);
selcon_de = editor_de.selectionController;
@ -88,15 +88,14 @@ function enFocus() {
editor_en.setSpellcheckUserOverride(true);
var inlineSpellChecker = editor_en.getInlineSpellChecker(true);
onSpellCheck(elem_en, function() {
maybeOnSpellCheck(elem_en, async function() {
var spellchecker = inlineSpellChecker.spellChecker;
let currentDictonary;
try {
currentDictonary = spellchecker.GetCurrentDictionary();
} catch (e) {}
let currentDictionaries = spellchecker.getCurrentDictionaries();
is(currentDictionaries.length, 1, "expected one dictionary");
let currentDictionary = currentDictionaries[0];
// Check that the English dictionary is loaded and that the spell check has worked.
is(currentDictonary, "en-US", "expected en-US");
is(currentDictionary, "en-US", "expected en-US");
is(getMisspelledWords(editor_en), "Nogoodword", "one misspelled word expected: Nogoodword");
// So far all was boring. The important thing is whether the spell check result
@ -106,7 +105,7 @@ function enFocus() {
is(sel.toString(), "German", "one misspelled word expected: German");
// Remove the fake de_DE dictionary again.
script.sendAsyncMessage("destroy");
await script.sendQuery("destroy");
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
elem_de.onfocus = null;
@ -114,7 +113,7 @@ function enFocus() {
elem_de.focus();
// After removal, the de_DE editor should refresh the spelling with en-US.
onSpellCheck(elem_de, function() {
maybeOnSpellCheck(elem_de, function() {
var endSel = selcon_de.getSelection(selcon_de.SELECTION_SPELLCHECK);
// eslint-disable-next-line no-useless-concat
is(endSel.toString(), "heute" + "ist" + "ein" + "guter",

View File

@ -32,13 +32,12 @@ var script;
/** Test for Bug 1209414 **/
/*
* All we want to do in this test is change the spelling using a right-click and selection from the menu.
* This is necessary since all the other tests use SetCurrentDictionary() which doesn't reflect
* This is necessary since all the other tests use setCurrentDictionaries() which doesn't reflect
* user behaviour.
*/
var onSpellCheck =
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck;
let {maybeOnSpellCheck, onSpellCheck} = SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(async function() {
@ -73,11 +72,9 @@ SimpleTest.waitForFocus(async function() {
// Select Language from the menu. Take a look at
// toolkit/modules/InlineSpellChecker.jsm to see how the menu works.
contextMenu.ownerDocument.getElementById("spell-check-dictionary-en-US")
.doCommand();
contextMenu.hidePopup();
return state;
});
addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
@ -94,15 +91,14 @@ SimpleTest.waitForFocus(async function() {
editor_de = SpecialPowers.wrap(elem_de).editor;
editor_de.setSpellcheckUserOverride(true);
onSpellCheck(elem_de, function() {
maybeOnSpellCheck(elem_de, function() {
var inlineSpellChecker = editor_de.getInlineSpellChecker(true);
var spellchecker = inlineSpellChecker.spellChecker;
try {
var currentDictonary = spellchecker.GetCurrentDictionary();
} catch (e) {}
let currentDictionaries = spellchecker.getCurrentDictionaries();
// Check that the German dictionary is loaded and that the spell check has worked.
is(currentDictonary, "de-DE", "expected de-DE");
is(currentDictionaries.length, 1, "expected one dictionary");
is(currentDictionaries[0], "de-DE", "expected de-DE");
// eslint-disable-next-line no-useless-concat
is(getMisspelledWords(editor_de), "today" + "is" + "a" + "good" + "day", "some misspelled words expected: today is a good day");
@ -110,7 +106,7 @@ SimpleTest.waitForFocus(async function() {
elem_de.focus();
// Make sure all spell checking action is done before right-click to select the en-US dictionary.
onSpellCheck(elem_de, function() {
maybeOnSpellCheck(elem_de, function() {
synthesizeMouse(elem_de, 2, 2, { type: "contextmenu", button: 2 }, window);
});
});
@ -120,25 +116,24 @@ async function handlePopup() {
var state = await script.sendQuery("hidepopup");
is(state, "open", "checking if popup is open");
onSpellCheck(elem_de, function() {
onSpellCheck(elem_de, async function() {
var inlineSpellChecker = editor_de.getInlineSpellChecker(true);
var spellchecker = inlineSpellChecker.spellChecker;
let currentDictonary;
try {
currentDictonary = spellchecker.GetCurrentDictionary();
} catch (e) {}
let currentDictionaries = spellchecker.getCurrentDictionaries();
// Check that the English dictionary is loaded and that the spell check has worked.
is(currentDictonary, "en-US", "expected en-US");
// eslint-disable-next-line no-useless-concat
is(getMisspelledWords(editor_de), "heute" + "ist" + "ein" + "guter", "some misspelled words expected: heute ist ein guter");
is(currentDictionaries.length, 2, "expected two dictionaries");
is(currentDictionaries[0], "de-DE", "expected de-DE");
is(currentDictionaries[1], "en-US", "expected en-US");
is(getMisspelledWords(editor_de), "", "No misspelled words expected");
// Remove the fake de_DE dictionary again.
script.sendAsyncMessage("destroy");
await script.sendQuery("destroy");
// This will clear the content preferences and reset "spellchecker.dictionary".
spellchecker.SetCurrentDictionary("");
SimpleTest.finish();
spellchecker.setCurrentDictionaries([]).then(() => {
SimpleTest.finish();
});
});
}

View File

@ -29,14 +29,14 @@ var spellchecker;
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(function() {
var onSpellCheck =
var maybeOnSpellCheck =
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", null).onSpellCheck;
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", {}).maybeOnSpellCheck;
var elem = document.getElementById("en-US");
elem.focus();
onSpellCheck(elem, function() {
maybeOnSpellCheck(elem, function() {
var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
var editor = editingSession.getEditorForWindow(window);
var selcon = editor.selectionController;

View File

@ -19,7 +19,7 @@
<div id="edit1" contenteditable=true></div>
<script>
const {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
const {maybeOnSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
SimpleTest.waitForExplicitFinish();
@ -52,7 +52,7 @@ async function test_with_single_quote(input) {
synthesizeKey("e");
synthesizeKey("s");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
let editor = getEditor(input);
// isSpellingCheckOk is defined in spellcheck.js
ok(isSpellingCheckOk(editor, misspeltWords), "no misspelt words");
@ -61,7 +61,7 @@ async function test_with_single_quote(input) {
synthesizeKey("\'");
is(input.value || input.textContent, "doesn\'", "");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
// XXX This won't work since mozInlineSpellWordUtil::SplitDOM removes
// last single quote unfortunately that is during inputting.
// isSpellingCheckOk is defined in spellcheck.js
@ -71,7 +71,7 @@ async function test_with_single_quote(input) {
synthesizeKey(" ");
is(input.value || input.textContent, "doesn\' ", "");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
misspeltWords.push("doesn");
// isSpellingCheckOk is defined in spellcheck.js
ok(isSpellingCheckOk(editor, misspeltWords), "should run spellchecker");
@ -95,7 +95,7 @@ async function test_with_twice_characters(input, ch) {
// trigger spellchecker
synthesizeKey(" ");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
misspeltWords.push("doesn");
let editor = getEditor(input);
// isSpellingCheckOk is defined in spellcheck.js
@ -115,7 +115,7 @@ async function test_between_single_quote(input) {
synthesizeKey("t");
synthesizeKey("\'");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
let editor = getEditor(input);
ok(isSpellingCheckOk(editor, misspeltWords),
"don't run spellchecker between single qoute");
@ -141,14 +141,14 @@ async function test_with_email(input) {
synthesizeKey("o");
synthesizeKey("m");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
let editor = getEditor(input);
ok(isSpellingCheckOk(editor, misspeltWords),
"don't run spellchecker for email address");
synthesizeKey(" ");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
ok(isSpellingCheckOk(editor, misspeltWords),
"no misspelt words due to email address");
}
@ -175,14 +175,14 @@ async function test_with_url(input) {
synthesizeKey("o");
synthesizeKey("m");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
let editor = getEditor(input);
ok(isSpellingCheckOk(editor, misspeltWords),
"don't run spellchecker for URL");
synthesizeKey(" ");
await new Promise((resolve) => { onSpellCheck(input, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(input, resolve); });
ok(isSpellingCheckOk(editor, misspeltWords),
"no misspelt words due to URL");
}

View File

@ -23,8 +23,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1497480
/** Test for Bug 1497480 **/
let gMisspeltWords = [];
let onSpellCheck = SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", null).onSpellCheck;
let maybeOnSpellCheck = SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", null).maybeOnSpellCheck;
const template = document.createElement("template");
template.innerHTML = `<div id="target" contenteditable>Test</div>`;
@ -52,7 +52,7 @@ add_task(async function() {
// Wait for first full spell-checking.
synthesizeMouseAtCenter(outOfTarget, {}, window);
await new Promise((resolve) => {
onSpellCheck(outOfTarget, function() {
maybeOnSpellCheck(outOfTarget, function() {
resolve();
});
});
@ -65,7 +65,7 @@ add_task(async function() {
gMisspeltWords.push("spellechek");
synthesizeMouseAtCenter(outOfTarget, {}, window);
await new Promise((resolve) => {
onSpellCheck(target, function() {
maybeOnSpellCheck(target, function() {
ok(isSpellingCheckOk(getEditor(), gMisspeltWords),
"Spell-checking should be performed when anchor navigates away from ShadowDOM");
SimpleTest.executeSoon(resolve);
@ -80,7 +80,7 @@ add_task(async function() {
gMisspeltWords.push("spellechck");
synthesizeKey("KEY_Enter", {}, window);
await new Promise((resolve) => {
onSpellCheck(target, function() {
maybeOnSpellCheck(target, function() {
ok(isSpellingCheckOk(getEditor(), gMisspeltWords),
"Spell-checking should be performed when pressing enter in contenteditable in ShadowDOM");
SimpleTest.executeSoon(resolve);

View File

@ -17,7 +17,7 @@
<div id="contenteditable" contenteditable=true>kkkk&#xf6;kkkk</div>
<script>
const {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
const {maybeOnSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
SimpleTest.waitForExplicitFinish();
@ -36,13 +36,13 @@ SimpleTest.waitForFocus(async () => {
synthesizeKey(" ");
// Run spell checker
await new Promise((resolve) => { onSpellCheck(contenteditable, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(contenteditable, resolve); });
synthesizeKey("a");
synthesizeKey("a");
synthesizeKey("a");
await new Promise((resolve) => { onSpellCheck(contenteditable, resolve); });
await new Promise((resolve) => { maybeOnSpellCheck(contenteditable, resolve); });
let editor = getEditor();
// isSpellingCheckOk is defined in spellcheck.js
// eslint-disable-next-line no-undef

View File

@ -35,18 +35,20 @@ function init() {
ok(list.length > 0, "At least one dictionary should be present");
var lang = list[0];
spellchecker.spellChecker.SetCurrentDictionary(lang);
onSpellCheck(textarea, function() {
spellchecker.spellChecker.setCurrentDictionaries([lang]).then(() => {
onSpellCheck(textarea, function() {
try {
var dictionary =
spellchecker.spellChecker.GetCurrentDictionary();
var dictionaries =
spellchecker.spellChecker.getCurrentDictionaries();
} catch (e) {}
is(dictionary, lang, "Unexpected spell check dictionary");
is(dictionaries.length, 1, "Expected one dictionary");
is(dictionaries[0], lang, "Unexpected spell check dictionary");
// This will clear the content preferences and reset "spellchecker.dictionary".
spellchecker.spellChecker.SetCurrentDictionary("");
SimpleTest.finish();
spellchecker.spellChecker.setCurrentDictionaries([]).then(() => {
SimpleTest.finish();
});
});
});
});
}

View File

@ -47,7 +47,7 @@ function runTest() {
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
.onSpellCheck(editDoc().documentElement, evalTest);
.maybeOnSpellCheck(editDoc().documentElement, evalTest);
}
function evalTest() {

View File

@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=432225
/** Test for Bug 432225 **/
let {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
let {maybeOnSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
SimpleTest.waitForExplicitFinish();
addLoadEvent(runTest);
@ -57,7 +57,7 @@ function addWords(aLimit) {
getEdit().focus();
sendString("aa OK ");
gMisspeltWords.push("aa");
onSpellCheck(editDoc(), function() {
maybeOnSpellCheck(editDoc(), function() {
addWords(aLimit - 1);
});
}

View File

@ -46,14 +46,14 @@ function runTest() {
var edit = document.getElementById("edit");
edit.focus();
const {onSpellCheck} = SpecialPowers.Cu.import(
const {maybeOnSpellCheck} = SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", null);
onSpellCheck(edit, function() {
maybeOnSpellCheck(edit, function() {
ok(isSpellingCheckOk(getEditor(), gMisspeltWords),
"All misspellings before editing are accounted for.");
append(" becaz I'm a lulcat!");
onSpellCheck(edit, function() {
maybeOnSpellCheck(edit, function() {
gMisspeltWords.push("becaz");
gMisspeltWords.push("lulcat");
ok(isSpellingCheckOk(getEditor(), gMisspeltWords),

View File

@ -64,36 +64,33 @@ var loadListener = async function(evt) {
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
.onSpellCheck(elem, function() {
var spellchecker = inlineSpellChecker.spellChecker;
try {
var currentDictonary = spellchecker.GetCurrentDictionary();
} catch (e) {}
if (!currentDictonary) {
spellchecker.SetCurrentDictionary("en-US");
}
.onSpellCheck(elem, async function() {
let spellchecker = inlineSpellChecker.spellChecker;
let currentDictionaries = spellchecker.getCurrentDictionaries();
is(currentDictionaries.length, 1, "expected one dictionary");
let currentDictionary = currentDictionaries[0];
if (firstLoad) {
firstLoad = false;
// First time around, the dictionary defaults to the locale.
is(currentDictonary, "en-US", "unexpected lang " + currentDictonary + " instead of en-US");
is(currentDictionary, "en-US", "unexpected lang " + currentDictionary + " instead of en-US");
// Select en-GB.
spellchecker.SetCurrentDictionary("en-GB");
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug678842_subframe.html?firstload=false";
spellchecker.setCurrentDictionaries(["en-GB"]).then(() => {
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug678842_subframe.html?firstload=false";
});
} else {
is(currentDictonary, "en-GB", "unexpected lang " + currentDictonary + " instead of en-GB");
is(currentDictionary, "en-GB", "unexpected lang " + currentDictionary + " instead of en-GB");
content.removeEventListener("load", loadListener);
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
script.sendAsyncMessage("destroy");
await script.sendQuery("destroy");
// This will clear the content preferences and reset "spellchecker.dictionary".
spellchecker.SetCurrentDictionary("");
SimpleTest.finish();
spellchecker.setCurrentDictionaries([]).then( () => {
SimpleTest.finish();
});
}
});
};

View File

@ -27,6 +27,11 @@ var elem_de;
var editor_de;
var script;
var maybeOnSpellCheck =
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
.maybeOnSpellCheck;
var onSpellCheck =
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
@ -69,14 +74,15 @@ function deFocus() {
editor_de.setSpellcheckUserOverride(true);
var inlineSpellChecker = editor_de.getInlineSpellChecker(true);
onSpellCheck(elem_de, function() {
maybeOnSpellCheck(elem_de, function() {
var spellchecker = inlineSpellChecker.spellChecker;
try {
var currentDictonary = spellchecker.GetCurrentDictionary();
var currentDictionaries = spellchecker.getCurrentDictionaries();
} catch (e) {}
// Check that the German dictionary is loaded and that the spell check has worked.
is(currentDictonary, "de-DE", "expected de-DE");
is(currentDictionaries.length, 1, "expected one dictionary");
is(currentDictionaries[0], "de-DE", "expected de-DE");
is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
// Now focus the other textarea, which requires English spelling.
@ -90,15 +96,13 @@ function enFocus() {
editor_en.setSpellcheckUserOverride(true);
var inlineSpellChecker = editor_en.getInlineSpellChecker(true);
onSpellCheck(elem_en, function() {
var spellchecker = inlineSpellChecker.spellChecker;
let currentDictonary;
try {
currentDictonary = spellchecker.GetCurrentDictionary();
} catch (e) {}
onSpellCheck(elem_en, async function() {
let spellchecker = inlineSpellChecker.spellChecker;
let currentDictionaries = spellchecker.getCurrentDictionaries();
// Check that the English dictionary is loaded and that the spell check has worked.
is(currentDictonary, "en-US", "expected en-US");
is(currentDictionaries.length, 1, "expected one dictionary");
is(currentDictionaries[0], "en-US", "expected en-US");
is(getMisspelledWords(editor_en), "Nogoodword", "one misspelled word expected: Nogoodword");
// So far all was boring. The important thing is whether the spell check result
@ -107,7 +111,7 @@ function enFocus() {
is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
// Remove the fake de_DE dictionary again.
script.sendAsyncMessage("destroy");
await script.sendQuery("destroy");
// Focus again, so the spelling gets updated, but before we need to kill the focus handler.
elem_de.onfocus = null;
@ -115,14 +119,15 @@ function enFocus() {
elem_de.focus();
// After removal, the de_DE editor should refresh the spelling with en-US.
onSpellCheck(elem_de, function() {
maybeOnSpellCheck(elem_de, function() {
spellchecker = inlineSpellChecker.spellChecker;
try {
currentDictonary = spellchecker.GetCurrentDictionary();
currentDictionaries = spellchecker.getCurrentDictionaries();
} catch (e) {}
// Check that the default English dictionary is loaded and that the spell check has worked.
is(currentDictonary, "en-US", "expected en-US");
is(currentDictionaries.length, 1, "expected one dictionary");
is(currentDictionaries[0], "en-US", "expected en-US");
// eslint-disable-next-line no-useless-concat
is(getMisspelledWords(editor_de), "heute" + "ist" + "ein" + "guter",
"some misspelled words expected: heute ist ein guter");

View File

@ -65,36 +65,37 @@ var loadListener = async function(evt) {
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm")
.onSpellCheck(elem, function() {
var spellchecker = inlineSpellChecker.spellChecker;
try {
var currentDictonary = spellchecker.GetCurrentDictionary();
} catch (e) {}
.onSpellCheck(elem, async function() {
let spellchecker = inlineSpellChecker.spellChecker;
let currentDictionaries = spellchecker.getCurrentDictionaries();
is(currentDictionaries.length, 1, "expected one dictionary");
let currentDictionary = currentDictionaries[0];
if (firstLoad) {
firstLoad = false;
// First time around, we get a random dictionary based on the language "en".
if (currentDictonary == "en-GB") {
spellchecker.SetCurrentDictionary("en-US");
if (currentDictionary == "en-GB") {
expected = "en-US";
} else if (currentDictonary == "en-US") {
spellchecker.SetCurrentDictionary("en-GB");
} else if (currentDictionary == "en-US") {
expected = "en-GB";
} else {
is(true, false, "Neither en-US nor en-GB are current");
}
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug717433_subframe.html?firstload=false";
spellchecker.setCurrentDictionaries([expected]).then(() => {
content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug717433_subframe.html?firstload=false";});
} else {
is(currentDictonary, expected, expected + " expected");
is(currentDictionary, expected, expected + " expected");
content.removeEventListener("load", loadListener);
// Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
script.sendAsyncMessage("destroy");
await script.sendQuery("destroy");
// This will clear the content preferences and reset "spellchecker.dictionary".
spellchecker.SetCurrentDictionary("");
SimpleTest.finish();
spellchecker.setCurrentDictionaries([]).then(() => {
SimpleTest.finish();
});
}
});
};

View File

@ -12,12 +12,12 @@
SimpleTest.waitForExplicitFinish();
SimpleTest.waitForFocus(async () => {
const { onSpellCheck } = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm");
const { maybeOnSpellCheck } = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm");
const editor = document.querySelector("div[contenteditable]");
async function replaceWord(aMisspelledWord, aCorrectWord, aReplaceAll) {
const editorObj = SpecialPowers.wrap(window).docShell.editingSession.getEditorForWindow(window);
const inlineSpellChecker = editorObj.getInlineSpellChecker(true);
await new Promise(resolve => onSpellCheck(editor, resolve));
await new Promise(resolve => maybeOnSpellCheck(editor, resolve));
const editorSpellCheck = inlineSpellChecker.spellChecker;
editorObj.beginTransaction();
try {

View File

@ -8,7 +8,7 @@
</head>
<body>
<script>
let {onSpellCheck} =
let {maybeOnSpellCheck} =
SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
function waitForTick() {
@ -30,7 +30,7 @@ async function waitForOnSpellCheck(
info(`Waiting for onSpellCheck (${aWhen})...`);
for (let retry = 0; retry < 100; retry++) {
await waitForTick();
await new Promise(resolve => onSpellCheck(aEditingHost, resolve));
await new Promise(resolve => maybeOnSpellCheck(aEditingHost, resolve));
if (aWaitForNumberOfMisspelledWords === 0) {
if (aSpellCheckSelection.rangeCount === 0) {
break;

View File

@ -13,7 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1729653
<body>
<textarea rows="20" cols="50">That undfgdfg seems OK.</textarea>
<script>
let {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
let {maybeOnSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
function waitForTick() {
return new Promise(resolve => SimpleTest.executeSoon(resolve));
@ -21,7 +21,7 @@ function waitForTick() {
function waitForOnSpellCheck(aTextArea) {
info("Waiting for onSpellCheck...");
return new Promise(resolve => onSpellCheck(aTextArea, resolve));
return new Promise(resolve => maybeOnSpellCheck(aTextArea, resolve));
}
/** Test for Bug 1729653 **/

View File

@ -15,14 +15,14 @@
add_task(async function() {
await new Promise(resolve => SimpleTest.waitForFocus(resolve));
let { onSpellCheck } =
let { maybeOnSpellCheck } =
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", null);
let element = document.getElementById("en-US");
element.focus();
await new Promise(resolve => onSpellCheck(element, resolve));
await new Promise(resolve => maybeOnSpellCheck(element, resolve));
let editingSession = SpecialPowers.wrap(window).docShell.editingSession;
let editor = editingSession.getEditorForWindow(window);

View File

@ -188,7 +188,7 @@ function do_run_test(checker, name, charset, todo_good, todo_bad) {
Assert.ok(good.exists() || bad.exists() || sug.exists());
dump("Setting dictionary to " + name + "\n");
checker.dictionary = name;
checker.dictionaries = [name];
if (good.exists()) {
var good_counter = 0;

View File

@ -34,7 +34,7 @@ add_task(async function() {
await OS.File.writeAtomic(affPath, new TextEncoder().encode(""));
spellCheck.loadDictionariesFromDir(baseDir);
spellCheck.dictionary = "dict";
spellCheck.dictionaries = ["dict"];
ok(
spellCheck.check(WORD),

View File

@ -27,12 +27,12 @@ function getDictionaryList(editor) {
function getCurrentDictionary(editor) {
var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
return spellchecker.GetCurrentDictionary();
return spellchecker.getCurrentDictionaries()[0];
}
function setCurrentDictionary(editor, dictionary) {
var spellchecker = editor.getInlineSpellChecker(true).spellChecker;
spellchecker.SetCurrentDictionary(dictionary);
return spellchecker.setCurrentDictionaries([dictionary]);
}
function RunTest() {
@ -65,9 +65,9 @@ function RunTest() {
ok(map.exists());
hunspell.addDirectory(map);
const {onSpellCheck} = ChromeUtils.import(
const {maybeOnSpellCheck} = ChromeUtils.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm");
onSpellCheck(textbox, function () {
maybeOnSpellCheck(textbox, function () {
// test that base and map dictionaries are available
var dicts = getDictionaryList(editor);
@ -75,48 +75,48 @@ function RunTest() {
isnot(dicts.indexOf("maputf"), -1, "map is available");
// select base dictionary
setCurrentDictionary(editor, "base-utf");
setCurrentDictionary(editor, "base-utf").then(() => {
/* eslint-disable no-useless-concat */
maybeOnSpellCheck(textbox, function () {
// test that base dictionary is in use
is(getMisspelledWords(editor), "Frühstück" + "qwertyu", "base misspellings");
is(getCurrentDictionary(editor), "base-utf", "current dictionary");
/* eslint-disable no-useless-concat */
onSpellCheck(textbox, function () {
// test that base dictionary is in use
is(getMisspelledWords(editor), "Frühstück" + "qwertyu", "base misspellings");
is(getCurrentDictionary(editor), "base-utf", "current dictionary");
// select map dictionary
setCurrentDictionary(editor, "maputf").then(() => {
// Focus again, so the spelling gets updated.
textbox.blur();
textbox.focus();
// select map dictionary
setCurrentDictionary(editor, "maputf");
maybeOnSpellCheck(textbox, function () {
// test that map dictionary is in use
is(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (1)");
is(getCurrentDictionary(editor), "maputf", "current dictionary");
// Focus again, so the spelling gets updated.
textbox.blur();
textbox.focus();
// uninstall map dictionary
hunspell.removeDirectory(map);
onSpellCheck(textbox, function () {
// test that map dictionary is in use
is(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (1)");
is(getCurrentDictionary(editor), "maputf", "current dictionary");
// Focus again, so the spelling gets updated.
textbox.blur();
textbox.focus();
// uninstall map dictionary
hunspell.removeDirectory(map);
maybeOnSpellCheck(textbox, function () {
// test that map dictionary is not in use
isnot(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (2)");
isnot(getCurrentDictionary(editor), "maputf", "current dictionary");
// Focus again, so the spelling gets updated.
textbox.blur();
textbox.focus();
// test that base dictionary is available and map dictionary is unavailable
var dicts = getDictionaryList(editor);
isnot(dicts.indexOf("base-utf"), -1, "base is available");
is(dicts.indexOf("maputf"), -1, "map is unavailable");
onSpellCheck(textbox, function () {
// test that map dictionary is not in use
isnot(getMisspelledWords(editor), "created" + "imply" + "tomorrow" + "qwertyu", "map misspellings (2)");
isnot(getCurrentDictionary(editor), "maputf", "current dictionary");
// uninstall base dictionary
hunspell.removeDirectory(base);
// test that base dictionary is available and map dictionary is unavailable
var dicts = getDictionaryList(editor);
isnot(dicts.indexOf("base-utf"), -1, "base is available");
is(dicts.indexOf("maputf"), -1, "map is unavailable");
// uninstall base dictionary
hunspell.removeDirectory(base);
onSpellCheck(textbox, function () {
SimpleTest.finish();
maybeOnSpellCheck(textbox, function () {
SimpleTest.finish();
});
});
});
});
});

View File

@ -14,7 +14,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1170484
/** Test for Bug 1170484 **/
SimpleTest.waitForExplicitFinish();
/* global onSpellCheck */
/* global maybeOnSpellCheck */
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);
@ -30,7 +30,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1170484
// Not sure why, but postponing through the event loop seems to be enough.
SimpleTest.executeSoon(function() {
synthesizeMouseAtCenter($('misspelled'), {}, window);
onSpellCheck($('area'), function() {
maybeOnSpellCheck($('area'), function() {
synthesizeMouseAtCenter($('misspelled'), {type: 'contextmenu'}, window);
var mm = SpecialPowers.loadChromeScript(SimpleTest.getTestFileURL('helper_bug1170484.js'))
info("Loaded chrome script");

View File

@ -29,7 +29,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1272623
async function performCorrection(misspelled, area) {
synthesizeMouseAtCenter($(misspelled), {}, window);
await new Promise(resolve => onSpellCheck($(area), resolve));
await new Promise(resolve => maybeOnSpellCheck($(area), resolve));
synthesizeMouseAtCenter($(misspelled), {type: 'contextmenu'}, window);
// Perform the spelling correction
@ -61,7 +61,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1272623
}
add_task(async function() {
/* global onSpellCheck */
/* global maybeOnSpellCheck */
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);

View File

@ -14,7 +14,7 @@ x
div.focus();
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);
onSpellCheck(div, function () {
maybeOnSpellCheck(div, function () {
var sel = window.getSelection();
sel.removeAllRanges();
var range = document.createRange();

View File

@ -21,7 +21,7 @@ x
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);
onSpellCheck(p.parentNode, function () {
maybeOnSpellCheck(p.parentNode, function () {
sendKey('DOWN'); // now after "1"
sendKey('DOWN'); // now make sure we get to the end
sendKey('DOWN'); // now make sure we get to the end

View File

@ -14,7 +14,7 @@ x
div.focus();
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);
onSpellCheck(div, function () {
maybeOnSpellCheck(div, function () {
var sel = window.getSelection();
sel.removeAllRanges();
var range = document.createRange();

View File

@ -21,7 +21,7 @@ x
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);
onSpellCheck(p.parentNode, function () {
maybeOnSpellCheck(p.parentNode, function () {
sendKey('DOWN'); // now after "1"
sendKey('DOWN'); // now below the P element
sendKey('UP'); // now before the "1"

View File

@ -5,7 +5,7 @@
document.body.firstChild.focus();
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);
onSpellCheck(document.body.firstChild, function() {
maybeOnSpellCheck(document.body.firstChild, function() {
document.documentElement.removeAttribute("class");
});
</script>

View File

@ -6,9 +6,9 @@ var div = document.body.firstChild;
div.focus();
SpecialPowers.Cu.import(
"resource://testing-common/AsyncSpellCheckTestHelper.jsm", window);
onSpellCheck(div, function() {
maybeOnSpellCheck(div, function() {
div.innerHTML = 'something missspelled<br>something elsed#';
onSpellCheck(div, function() {
maybeOnSpellCheck(div, function() {
document.documentElement.removeAttribute("class");
});
});

View File

@ -169,7 +169,7 @@ add_task(async function test_validation() {
const WORD = "Flehgragh";
add_task(async function test_registration() {
spellCheck.dictionary = "en-US";
spellCheck.dictionaries = ["en-US"];
ok(!spellCheck.check(WORD), "Word should not pass check before add-on loads");