summaryrefslogtreecommitdiffstats
path: root/editor/spellchecker/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /editor/spellchecker/tests
parentInitial commit. (diff)
downloadfirefox-2aa4a82499d4becd2284cdb482213d541b8804dd.tar.xz
firefox-2aa4a82499d4becd2284cdb482213d541b8804dd.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'editor/spellchecker/tests')
-rw-r--r--editor/spellchecker/tests/.eslintrc.js5
-rw-r--r--editor/spellchecker/tests/bug1200533_subframe.html15
-rw-r--r--editor/spellchecker/tests/bug1204147_subframe.html11
-rw-r--r--editor/spellchecker/tests/bug1204147_subframe2.html9
-rw-r--r--editor/spellchecker/tests/bug678842_subframe.html8
-rw-r--r--editor/spellchecker/tests/bug717433_subframe.html8
-rw-r--r--editor/spellchecker/tests/de-DE/de_DE.aff2
-rw-r--r--editor/spellchecker/tests/de-DE/de_DE.dic6
-rw-r--r--editor/spellchecker/tests/en-AU/en_AU.aff2
-rw-r--r--editor/spellchecker/tests/en-AU/en_AU.dic4
-rw-r--r--editor/spellchecker/tests/en-GB/en_GB.aff2
-rw-r--r--editor/spellchecker/tests/en-GB/en_GB.dic4
-rw-r--r--editor/spellchecker/tests/mochitest.ini34
-rw-r--r--editor/spellchecker/tests/test_async_UpdateCurrentDictionary.html74
-rw-r--r--editor/spellchecker/tests/test_bug1200533.html159
-rw-r--r--editor/spellchecker/tests/test_bug1204147.html115
-rw-r--r--editor/spellchecker/tests/test_bug1205983.html135
-rw-r--r--editor/spellchecker/tests/test_bug1209414.html148
-rw-r--r--editor/spellchecker/tests/test_bug1219928.html69
-rw-r--r--editor/spellchecker/tests/test_bug1365383.html45
-rw-r--r--editor/spellchecker/tests/test_bug1418629.html209
-rw-r--r--editor/spellchecker/tests/test_bug1602526.html56
-rw-r--r--editor/spellchecker/tests/test_bug338427.html60
-rw-r--r--editor/spellchecker/tests/test_bug678842.html108
-rw-r--r--editor/spellchecker/tests/test_bug697981.html138
-rw-r--r--editor/spellchecker/tests/test_bug717433.html109
26 files changed, 1535 insertions, 0 deletions
diff --git a/editor/spellchecker/tests/.eslintrc.js b/editor/spellchecker/tests/.eslintrc.js
new file mode 100644
index 0000000000..845ed3f013
--- /dev/null
+++ b/editor/spellchecker/tests/.eslintrc.js
@@ -0,0 +1,5 @@
+"use strict";
+
+module.exports = {
+ extends: ["plugin:mozilla/mochitest-test"],
+};
diff --git a/editor/spellchecker/tests/bug1200533_subframe.html b/editor/spellchecker/tests/bug1200533_subframe.html
new file mode 100644
index 0000000000..f095c0601f
--- /dev/null
+++ b/editor/spellchecker/tests/bug1200533_subframe.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Language" content="en-US">
+</head>
+<body>
+<textarea id="none">root en-US</textarea>
+<textarea id="en-GB" lang="en-GB">root en-US, but element en-GB</textarea>
+<textarea id="en-gb" lang="en-gb">root en-US, but element en-gb (lower case)</textarea>
+<textarea id="en-ZA-not-avail" lang="en-ZA">root en-US, but element en-ZA (which is not installed)</textarea>
+<textarea id="en-generic" lang="en">root en-US, but element en</textarea>
+<textarea id="en" lang="en">root en-US, but element en</textarea>
+<textarea id="ko-not-avail" lang="ko">root en-US, but element ko (which is not installed)</textarea>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/bug1204147_subframe.html b/editor/spellchecker/tests/bug1204147_subframe.html
new file mode 100644
index 0000000000..a9b1225cd9
--- /dev/null
+++ b/editor/spellchecker/tests/bug1204147_subframe.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<textarea id="en-GB" lang="en-GB">element en-GB</textarea>
+<textarea id="en-US" lang="testing-XX">element should default to en-US</textarea>
+
+<div id="trouble-maker" contenteditable>the presence of this div triggers the faulty code path</div>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/bug1204147_subframe2.html b/editor/spellchecker/tests/bug1204147_subframe2.html
new file mode 100644
index 0000000000..935777bd99
--- /dev/null
+++ b/editor/spellchecker/tests/bug1204147_subframe2.html
@@ -0,0 +1,9 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<textarea id="en-GB" lang="en-GB">element en-GB</textarea>
+<textarea id="en-US" lang="testing-XX">element should default to en-US</textarea>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/bug678842_subframe.html b/editor/spellchecker/tests/bug678842_subframe.html
new file mode 100644
index 0000000000..39d578ee41
--- /dev/null
+++ b/editor/spellchecker/tests/bug678842_subframe.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<textarea id="textarea" lang="testing-XXX"></textarea>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/bug717433_subframe.html b/editor/spellchecker/tests/bug717433_subframe.html
new file mode 100644
index 0000000000..3c2927e88f
--- /dev/null
+++ b/editor/spellchecker/tests/bug717433_subframe.html
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<textarea id="textarea" lang="en"></textarea>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/de-DE/de_DE.aff b/editor/spellchecker/tests/de-DE/de_DE.aff
new file mode 100644
index 0000000000..5dc6896b6d
--- /dev/null
+++ b/editor/spellchecker/tests/de-DE/de_DE.aff
@@ -0,0 +1,2 @@
+# Affix file for German English dictionary
+# Fake file, nothing here.
diff --git a/editor/spellchecker/tests/de-DE/de_DE.dic b/editor/spellchecker/tests/de-DE/de_DE.dic
new file mode 100644
index 0000000000..415c216861
--- /dev/null
+++ b/editor/spellchecker/tests/de-DE/de_DE.dic
@@ -0,0 +1,6 @@
+5
+ein
+guter
+heute
+ist
+Tag
diff --git a/editor/spellchecker/tests/en-AU/en_AU.aff b/editor/spellchecker/tests/en-AU/en_AU.aff
new file mode 100644
index 0000000000..e0c467248d
--- /dev/null
+++ b/editor/spellchecker/tests/en-AU/en_AU.aff
@@ -0,0 +1,2 @@
+# Affix file for British English dictionary
+# Fake file, nothing here.
diff --git a/editor/spellchecker/tests/en-AU/en_AU.dic b/editor/spellchecker/tests/en-AU/en_AU.dic
new file mode 100644
index 0000000000..0a1be725d4
--- /dev/null
+++ b/editor/spellchecker/tests/en-AU/en_AU.dic
@@ -0,0 +1,4 @@
+3
+Mary
+Paul
+Peter
diff --git a/editor/spellchecker/tests/en-GB/en_GB.aff b/editor/spellchecker/tests/en-GB/en_GB.aff
new file mode 100644
index 0000000000..e0c467248d
--- /dev/null
+++ b/editor/spellchecker/tests/en-GB/en_GB.aff
@@ -0,0 +1,2 @@
+# Affix file for British English dictionary
+# Fake file, nothing here.
diff --git a/editor/spellchecker/tests/en-GB/en_GB.dic b/editor/spellchecker/tests/en-GB/en_GB.dic
new file mode 100644
index 0000000000..0a1be725d4
--- /dev/null
+++ b/editor/spellchecker/tests/en-GB/en_GB.dic
@@ -0,0 +1,4 @@
+3
+Mary
+Paul
+Peter
diff --git a/editor/spellchecker/tests/mochitest.ini b/editor/spellchecker/tests/mochitest.ini
new file mode 100644
index 0000000000..a3bc9a683b
--- /dev/null
+++ b/editor/spellchecker/tests/mochitest.ini
@@ -0,0 +1,34 @@
+[DEFAULT]
+prefs =
+ gfx.font_loader.delay=0
+ gfx.font_loader.interval=0
+ gfx.font_rendering.fallback.async=false
+
+skip-if = os == 'android'
+support-files =
+ bug678842_subframe.html
+ bug717433_subframe.html
+ bug1200533_subframe.html
+ bug1204147_subframe.html
+ bug1204147_subframe2.html
+ en-GB/en_GB.dic
+ en-GB/en_GB.aff
+ en-AU/en_AU.dic
+ en-AU/en_AU.aff
+ de-DE/de_DE.dic
+ de-DE/de_DE.aff
+ !/editor/libeditor/tests/spellcheck.js
+
+[test_async_UpdateCurrentDictionary.html]
+[test_bug678842.html]
+[test_bug697981.html]
+[test_bug717433.html]
+[test_bug1200533.html]
+[test_bug1204147.html]
+[test_bug1205983.html]
+[test_bug1209414.html]
+[test_bug1219928.html]
+skip-if = e10s
+[test_bug1365383.html]
+[test_bug1418629.html]
+[test_bug1602526.html]
diff --git a/editor/spellchecker/tests/test_async_UpdateCurrentDictionary.html b/editor/spellchecker/tests/test_async_UpdateCurrentDictionary.html
new file mode 100644
index 0000000000..f95e353569
--- /dev/null
+++ b/editor/spellchecker/tests/test_async_UpdateCurrentDictionary.html
@@ -0,0 +1,74 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=856270
+-->
+<head>
+ <title>Test for Bug 856270 - Async UpdateCurrentDictionary</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=856270">Mozilla Bug 856270</a>
+<p id="display"></p>
+<div id="content">
+<textarea id="editor" spellcheck="true"></textarea>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(start);
+
+function start() {
+ var textarea = document.getElementById("editor");
+ textarea.focus();
+
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck(textarea, function() {
+ 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.");
+
+ // 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();
+ }
+ });
+ }
+ 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>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1200533.html b/editor/spellchecker/tests/test_bug1200533.html
new file mode 100644
index 0000000000..107e54cb4e
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1200533.html
@@ -0,0 +1,159 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1200533
+-->
+<head>
+ <title>Test for Bug 1200533</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1200533">Mozilla Bug 1200533</a>
+<p id="display"></p>
+<iframe id="content"></iframe>
+
+</div>
+<pre id="test">
+<script class="testbody" ttype="application/javascript">
+
+/** Test for Bug 1200533 **/
+/** Visit the elements defined above and check the dictionary we got **/
+SimpleTest.waitForExplicitFinish();
+var content = document.getElementById("content");
+
+var tests = [
+ // text area, value of spellchecker.dictionary, result.
+ // Result: Document language.
+ [ "none", "", "en-US" ],
+ // Result: Element language.
+ [ "en-GB", "", "en-GB" ],
+ [ "en-gb", "", "en-GB" ],
+ // Result: Random en-* or en-US (if application locale is en-US).
+ [ "en-ZA-not-avail", "", "*" ],
+ [ "en-generic", "", "*" ],
+ [ "en", "", "*" ],
+ // Result: Locale.
+ [ "ko-not-avail", "", "en-US" ],
+
+ // Result: Preference value in all cases.
+ [ "en-ZA-not-avail", "en-AU", "en-AU" ],
+ [ "en-generic", "en-AU", "en-AU" ],
+ [ "ko-not-avail", "en-AU", "en-AU" ],
+
+ // Result: Random en-*.
+ [ "en-ZA-not-avail", "de-DE", "*" ],
+ [ "en-generic", "de-DE", "*" ],
+ // Result: Preference value.
+ [ "ko-not-avail", "de-DE", "de-DE" ],
+ ];
+
+var loadCount = 0;
+var retrying = false;
+var script;
+
+var loadListener = async function(evt) {
+ if (loadCount == 0) {
+ /* eslint-env mozilla/frame-script */
+ script = SpecialPowers.loadChromeScript(function() {
+ // eslint-disable-next-line mozilla/use-services
+ var 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");
+
+ var hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Install en-GB, en-AU and de-DE dictionaries.
+ var en_GB = dir.clone();
+ var en_AU = dir.clone();
+ var de_DE = dir.clone();
+ en_GB.append("en-GB");
+ en_AU.append("en-AU");
+ de_DE.append("de-DE");
+ hunspell.addDirectory(en_GB);
+ hunspell.addDirectory(en_AU);
+ hunspell.addDirectory(de_DE);
+
+ addMessageListener("check-existence",
+ () => [en_GB.exists(), en_AU.exists(),
+ de_DE.exists()]);
+ addMessageListener("destroy", () => {
+ hunspell.removeDirectory(en_GB);
+ hunspell.removeDirectory(en_AU);
+ hunspell.removeDirectory(de_DE);
+ });
+ });
+ var existenceChecks = await script.sendQuery("check-existence");
+ is(existenceChecks[0], true, "true expected (en-GB directory should exist)");
+ is(existenceChecks[1], true, "true expected (en-AU directory should exist)");
+ is(existenceChecks[2], true, "true expected (de-DE directory should exist)");
+ }
+
+ SpecialPowers.pushPrefEnv({set: [["spellchecker.dictionary", tests[loadCount][1]]]},
+ function() { continueTest(evt); });
+};
+
+function continueTest(evt) {
+ var doc = evt.target.contentDocument;
+ var elem = doc.getElementById(tests[loadCount][0]);
+ var editor = SpecialPowers.wrap(elem).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+ const is_en_US = SpecialPowers.Services.locale.appLocaleAsBCP47 == "en-US";
+
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck(elem, function() {
+ var spellchecker = inlineSpellChecker.spellChecker;
+ try {
+ var dict = spellchecker.GetCurrentDictionary();
+ } catch (e) {}
+
+ if (!dict && !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
+ // by reloading the iframe without bumping loadCount.
+ info(`No current dictionary: retrying testcase ${loadCount}`);
+ retrying = true;
+ } else {
+ if (tests[loadCount][2] != "*") {
+ is(dict, tests[loadCount][2], "expected " + tests[loadCount][2]);
+ } else if (is_en_US && tests[loadCount][0].startsWith("en")) {
+ // Current application locale is en-US and content lang is en or
+ // en-unknown, so we should use en-US dictionary as default.
+ is(dict, "en-US", "expected en-US that is application locale");
+ } else {
+ var gotEn = (dict == "en-GB" || dict == "en-AU" || dict == "en-US");
+ is(gotEn, true, "expected en-AU or en-GB or en-US");
+ }
+
+ loadCount++;
+ retrying = false;
+ }
+
+ if (loadCount < tests.length) {
+ // Load the iframe again.
+ 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");
+
+ SimpleTest.finish();
+ }
+ });
+}
+
+content.addEventListener("load", loadListener);
+
+content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1200533_subframe.html?firstload=true";
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1204147.html b/editor/spellchecker/tests/test_bug1204147.html
new file mode 100644
index 0000000000..e009e1c432
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1204147.html
@@ -0,0 +1,115 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1204147
+-->
+<head>
+ <title>Test for Bug 1204147</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1204147">Mozilla Bug 1204147</a>
+<p id="display"></p>
+<iframe id="content"></iframe>
+</div>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 1204147 **/
+SimpleTest.waitForExplicitFinish();
+var content = document.getElementById("content");
+// Load a subframe containing an editor with using "en-GB". At first
+// load, it will set the dictionary to "en-GB". The bug was that a content preference
+// was also created. At second load, we check the dictionary for another element,
+// one that should use "en-US". With the bug corrected, we get "en-US", before
+// we got "en-GB" from the content preference.
+
+var firstLoad = true;
+var script;
+
+var loadListener = async function(evt) {
+ if (firstLoad) {
+ /* eslint-env mozilla/frame-script */
+ script = SpecialPowers.loadChromeScript(function() {
+ // eslint-disable-next-line mozilla/use-services
+ var 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");
+
+ var hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Install en-GB dictionary.
+ let en_GB = dir.clone();
+ en_GB.append("en-GB");
+ hunspell.addDirectory(en_GB);
+
+ addMessageListener("en_GB-exists", () => en_GB.exists());
+ addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
+ });
+ is(await script.sendQuery("en_GB-exists"), true,
+ "true expected (en-GB directory should exist)");
+ }
+
+ var doc = evt.target.contentDocument;
+ var elem;
+ if (firstLoad) {
+ elem = doc.getElementById("en-GB");
+ } else {
+ elem = doc.getElementById("en-US");
+ }
+
+ var editor = SpecialPowers.wrap(elem).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck(elem, function() {
+ var spellchecker = inlineSpellChecker.spellChecker;
+ try {
+ var currentDictonary = spellchecker.GetCurrentDictionary();
+ } catch (e) {}
+
+ 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");
+
+ // 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
+ // doesn't allow the retrieval of the spell check dictionary used for the element,
+ // because the trouble-maker causes the 'global' spell check dictionary to be set to "en-GB"
+ // (since it picks the first one from the list) before we have the chance to retrieve
+ // the dictionary for the element (which happens asynchonously after the spell check has completed).
+ content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1204147_subframe2.html?firstload=false";
+ } 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");
+ content.removeEventListener("load", loadListener);
+
+ // Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
+ script.sendAsyncMessage("destroy");
+
+ // Reset the preference, so the last value we set doesn't collide with the next test.
+ SimpleTest.finish();
+ }
+ });
+};
+
+content.addEventListener("load", loadListener);
+
+content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug1204147_subframe.html?firstload=true";
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1205983.html b/editor/spellchecker/tests/test_bug1205983.html
new file mode 100644
index 0000000000..e85bb5efdb
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1205983.html
@@ -0,0 +1,135 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1205983
+-->
+<head>
+ <title>Test for Bug 1205983</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1205983">Mozilla Bug 1205983</a>
+<p id="display"></p>
+</div>
+
+<div contenteditable id="de-DE" lang="de-DE" onfocus="deFocus()">German heute ist ein guter Tag</div>
+<textarea id="en-US" lang="en-US" onfocus="enFocus()">Nogoodword today is a nice day</textarea>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+function getMisspelledWords(editor) {
+ return editor.selectionController.getSelection(SpecialPowers.Ci.nsISelectionController.SELECTION_SPELLCHECK).toString();
+}
+
+var elem_de;
+var editor_de;
+var selcon_de;
+var script;
+
+var onSpellCheck =
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck;
+
+/** Test for Bug 1205983 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(async function() {
+ /* eslint-env mozilla/frame-script */
+ script = SpecialPowers.loadChromeScript(function() {
+ // eslint-disable-next-line mozilla/use-services
+ var 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");
+
+ var hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Install de-DE dictionary.
+ var de_DE = dir.clone();
+ de_DE.append("de-DE");
+ hunspell.addDirectory(de_DE);
+
+ addMessageListener("de_DE-exists", () => de_DE.exists());
+ addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
+ });
+ is(await script.sendQuery("de_DE-exists"), true,
+ "true expected (de_DE directory should exist)");
+
+ document.getElementById("de-DE").focus();
+});
+
+function deFocus() {
+ elem_de = document.getElementById("de-DE");
+
+ onSpellCheck(elem_de, function() {
+ var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
+ editor_de = editingSession.getEditorForWindow(window);
+ selcon_de = editor_de.selectionController;
+ var sel = selcon_de.getSelection(selcon_de.SELECTION_SPELLCHECK);
+
+ // Check that we spelled in German, so there is only one misspelled word.
+ is(sel.toString(), "German", "one misspelled word expected: German");
+
+ // Now focus the textarea, which requires English spelling.
+ document.getElementById("en-US").focus();
+ });
+}
+
+function enFocus() {
+ var elem_en = document.getElementById("en-US");
+ var editor_en =
+ SpecialPowers.wrap(elem_en)
+ .editor;
+ 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) {}
+
+ // Check that the English dictionary is loaded and that the spell check has worked.
+ is(currentDictonary, "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
+ // in the de-DE editor is still the same. After losing focus, no spell check
+ // updates should take place there.
+ var sel = selcon_de.getSelection(selcon_de.SELECTION_SPELLCHECK);
+ is(sel.toString(), "German", "one misspelled word expected: German");
+
+ // Remove the fake de_DE dictionary again.
+ script.sendAsyncMessage("destroy");
+
+ // Focus again, so the spelling gets updated, but before we need to kill the focus handler.
+ elem_de.onfocus = null;
+ elem_de.blur();
+ elem_de.focus();
+
+ // After removal, the de_DE editor should refresh the spelling with en-US.
+ onSpellCheck(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",
+ "some misspelled words expected: heute ist ein guter");
+
+ // If we don't reset this, we cause massive leaks.
+ selcon_de = null;
+ editor_de = null;
+
+ SimpleTest.finish();
+ });
+ });
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1209414.html b/editor/spellchecker/tests/test_bug1209414.html
new file mode 100644
index 0000000000..aeb9b82274
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1209414.html
@@ -0,0 +1,148 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1209414
+-->
+<head>
+ <title>Test for Bug 1209414</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>
+<p id="display"></p>
+</div>
+
+<textarea id="de-DE" lang="de-DE">heute ist ein guter Tag - today is a good day</textarea>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+const Ci = SpecialPowers.Ci;
+
+function getMisspelledWords(editor) {
+ return editor.selectionController.getSelection(Ci.nsISelectionController.SELECTION_SPELLCHECK).toString();
+}
+
+var elem_de;
+var editor_de;
+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
+ * user behaviour.
+ */
+
+var onSpellCheck =
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm").onSpellCheck;
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(async function() {
+ /* global actorParent */
+ /* eslint-env mozilla/frame-script */
+ script = SpecialPowers.loadChromeScript(function() {
+ var chromeWin = actorParent.rootFrameLoader
+ .ownerElement.ownerGlobal.browsingContext.topChromeWindow;
+ var contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
+ contextMenu.addEventListener("popupshown",
+ () => sendAsyncMessage("popupshown"));
+
+ // eslint-disable-next-line mozilla/use-services
+ var 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");
+
+ var 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("hidepopup", function() {
+ var state = contextMenu.state;
+
+ // 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));
+ addMessageListener("contextMenu-not-null", () => contextMenu != null);
+ addMessageListener("de_DE-exists", () => de_DE.exists());
+ });
+ is(await script.sendQuery("contextMenu-not-null"), true,
+ "Got context menu XUL");
+ is(await script.sendQuery("de_DE-exists"), true,
+ "true expected (de_DE directory should exist)");
+ script.addMessageListener("popupshown", handlePopup);
+
+ elem_de = document.getElementById("de-DE");
+ editor_de = SpecialPowers.wrap(elem_de).editor;
+ editor_de.setSpellcheckUserOverride(true);
+
+ onSpellCheck(elem_de, function() {
+ var inlineSpellChecker = editor_de.getInlineSpellChecker(true);
+ var spellchecker = inlineSpellChecker.spellChecker;
+ try {
+ var currentDictonary = spellchecker.GetCurrentDictionary();
+ } catch (e) {}
+
+ // Check that the German dictionary is loaded and that the spell check has worked.
+ is(currentDictonary, "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");
+
+ // Focus again, just to be sure that the context-click won't trigger another spell check.
+ elem_de.focus();
+
+ // Make sure all spell checking action is done before right-click to select the en-US dictionary.
+ onSpellCheck(elem_de, function() {
+ synthesizeMouse(elem_de, 2, 2, { type: "contextmenu", button: 2 }, window);
+ });
+ });
+});
+
+async function handlePopup() {
+ var state = await script.sendQuery("hidepopup");
+ is(state, "open", "checking if popup is open");
+
+ onSpellCheck(elem_de, function() {
+ var inlineSpellChecker = editor_de.getInlineSpellChecker(true);
+ var spellchecker = inlineSpellChecker.spellChecker;
+ let currentDictonary;
+ try {
+ currentDictonary = spellchecker.GetCurrentDictionary();
+ } catch (e) {}
+
+ // 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");
+
+ // Remove the fake de_DE dictionary again.
+ script.sendAsyncMessage("destroy");
+
+ // This will clear the content preferences and reset "spellchecker.dictionary".
+ spellchecker.SetCurrentDictionary("");
+ SimpleTest.finish();
+ });
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1219928.html b/editor/spellchecker/tests/test_bug1219928.html
new file mode 100644
index 0000000000..bbd8f80cd7
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1219928.html
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1219928
+-->
+<head>
+ <title>Test for Bug 1219928</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1219928">Mozilla Bug 1219928</a>
+<p id="display"></p>
+
+<div contenteditable id="en-US" lang="en-US">
+<p>And here a missspelled word</p>
+<style>
+<!-- and here another onnee in a style comment -->
+</style>
+</div>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 1219928 **/
+/* Very simple test to check that <style> blocks are skipped in the spell check */
+
+var spellchecker;
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ var onSpellCheck =
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm", null).onSpellCheck;
+
+ var elem = document.getElementById("en-US");
+ elem.focus();
+
+ onSpellCheck(elem, function() {
+ var editingSession = SpecialPowers.wrap(window).docShell.editingSession;
+ var editor = editingSession.getEditorForWindow(window);
+ var selcon = editor.selectionController;
+ var sel = selcon.getSelection(selcon.SELECTION_SPELLCHECK);
+
+ is(sel.toString(), "missspelled", "one misspelled word expected: missspelled");
+
+ spellchecker = SpecialPowers.Cu.createSpellChecker();
+ spellchecker.setFilterType(spellchecker.FILTERTYPE_NORMAL);
+ spellchecker.InitSpellChecker(editor, false, spellCheckStarted);
+ });
+});
+
+function spellCheckStarted() {
+ var misspelledWord = spellchecker.GetNextMisspelledWord();
+ is(misspelledWord, "missspelled", "first misspelled word expected: missspelled");
+
+ // Without the fix, the next misspelled word was 'onnee', so we check that we don't get it.
+ misspelledWord = spellchecker.GetNextMisspelledWord();
+ isnot(misspelledWord, "onnee", "second misspelled word should not be: onnee");
+
+ spellchecker = "";
+
+ SimpleTest.finish();
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1365383.html b/editor/spellchecker/tests/test_bug1365383.html
new file mode 100644
index 0000000000..5b3e238528
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1365383.html
@@ -0,0 +1,45 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1365383
+-->
+<head>
+ <title>Test for Bug 1365383</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1365383">Mozilla Bug 1365383</a>
+<p id="display"></p>
+<div id="content">
+<textarea id="editor" spellcheck="true"></textarea>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(() => {
+ let textarea = document.getElementById("editor");
+ let editor = SpecialPowers.wrap(textarea).editor;
+
+ let spellChecker = SpecialPowers.Cu.createSpellChecker();
+
+ // Callback parameter isn't set
+ spellChecker.InitSpellChecker(editor, false);
+
+ textarea.focus();
+
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck(textarea, () => {
+ // Callback parameter isn't set
+ spellChecker.UpdateCurrentDictionary();
+
+ var canSpellCheck = spellChecker.canSpellCheck();
+ ok(canSpellCheck, "spellCheck is enabled");
+ SimpleTest.finish();
+ });
+});
+</script>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1418629.html b/editor/spellchecker/tests/test_bug1418629.html
new file mode 100644
index 0000000000..4f0014c45b
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1418629.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Mozilla bug 1418629</title>
+ <link rel=stylesheet href="/tests/SimpleTest/test.css">
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/AddTask.js"></script>
+ <script src="/tests/editor/libeditor/tests/spellcheck.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1418629">Mozilla Bug 1418629</a>
+<p id="display"></p>
+<div id="content" style="display: none;">
+
+</div>
+
+<input id="input1" spellcheck="true">
+<textarea id="textarea1"></textarea>
+<div id="edit1" contenteditable=true></div>
+
+<script>
+const {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
+
+SimpleTest.waitForExplicitFinish();
+
+function getEditor(input) {
+ if (input instanceof HTMLInputElement ||
+ input instanceof HTMLTextAreaElement) {
+ return SpecialPowers.wrap(input).editor;
+ }
+
+ return SpecialPowers.wrap(window).docShell.editor;
+}
+
+function resetEditableContent(input) {
+ if (input instanceof HTMLInputElement ||
+ input instanceof HTMLTextAreaElement) {
+ input.value = "";
+ return;
+ }
+ input.innerHTML = "";
+}
+
+async function test_with_single_quote(input) {
+ let misspeltWords = [];
+
+ input.focus();
+ resetEditableContent(input);
+
+ synthesizeKey("d");
+ synthesizeKey("o");
+ synthesizeKey("e");
+ synthesizeKey("s");
+
+ await new Promise((resolve) => { onSpellCheck(input, resolve); });
+ let editor = getEditor(input);
+ // isSpellingCheckOk is defined in spellcheck.js
+ ok(isSpellingCheckOk(editor, misspeltWords), "no misspelt words");
+
+ synthesizeKey("n");
+ synthesizeKey("\'");
+ is(input.value || input.textContent, "doesn\'", "");
+
+ await new Promise((resolve) => { onSpellCheck(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
+ todo_is(isSpellingCheckOk(editor, misspeltWords, true), true,
+ "don't run spellchecker during inputting word");
+
+ synthesizeKey(" ");
+ is(input.value || input.textContent, "doesn\' ", "");
+
+ await new Promise((resolve) => { onSpellCheck(input, resolve); });
+ misspeltWords.push("doesn");
+ // isSpellingCheckOk is defined in spellcheck.js
+ ok(isSpellingCheckOk(editor, misspeltWords), "should run spellchecker");
+}
+
+async function test_with_twice_characters(input, ch) {
+ let misspeltWords = [];
+
+ input.focus();
+ resetEditableContent(input);
+
+ synthesizeKey("d");
+ synthesizeKey("o");
+ synthesizeKey("e");
+ synthesizeKey("s");
+ synthesizeKey("n");
+ synthesizeKey(ch);
+ synthesizeKey(ch);
+ is(input.value || input.textContent, "doesn" + ch + ch, "");
+
+ // trigger spellchecker
+ synthesizeKey(" ");
+
+ await new Promise((resolve) => { onSpellCheck(input, resolve); });
+ misspeltWords.push("doesn");
+ let editor = getEditor(input);
+ // isSpellingCheckOk is defined in spellcheck.js
+ ok(isSpellingCheckOk(editor, misspeltWords), "should run spellchecker");
+}
+
+async function test_between_single_quote(input) {
+ let misspeltWords = [];
+
+ input.focus();
+ resetEditableContent(input);
+
+ synthesizeKey("\'");
+ synthesizeKey("t");
+ synthesizeKey("e");
+ synthesizeKey("s");
+ synthesizeKey("t");
+ synthesizeKey("\'");
+
+ await new Promise((resolve) => { onSpellCheck(input, resolve); });
+ let editor = getEditor(input);
+ ok(isSpellingCheckOk(editor, misspeltWords),
+ "don't run spellchecker between single qoute");
+}
+
+async function test_with_email(input) {
+ let misspeltWords = [];
+
+ input.focus();
+ resetEditableContent(input);
+
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("@");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey(".");
+ synthesizeKey("c");
+ synthesizeKey("o");
+ synthesizeKey("m");
+
+ await new Promise((resolve) => { onSpellCheck(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); });
+ ok(isSpellingCheckOk(editor, misspeltWords),
+ "no misspelt words due to email address");
+}
+
+async function test_with_url(input) {
+ let misspeltWords = [];
+
+ input.focus();
+ resetEditableContent(input);
+
+ synthesizeKey("h");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("p");
+ synthesizeKey(":");
+ synthesizeKey("/");
+ synthesizeKey("/");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey("t");
+ synthesizeKey(".");
+ synthesizeKey("c");
+ synthesizeKey("o");
+ synthesizeKey("m");
+
+ await new Promise((resolve) => { onSpellCheck(input, resolve); });
+ let editor = getEditor(input);
+ ok(isSpellingCheckOk(editor, misspeltWords),
+ "don't run spellchecker for URL");
+
+ synthesizeKey(" ");
+
+ await new Promise((resolve) => { onSpellCheck(input, resolve); });
+ ok(isSpellingCheckOk(editor, misspeltWords),
+ "no misspelt words due to URL");
+}
+
+SimpleTest.waitForFocus(() => {
+ for (let n of ["input1", "textarea1", "edit1"]) {
+ add_task(test_with_single_quote.bind(null,
+ document.getElementById(n)));
+ add_task(test_with_twice_characters.bind(null,
+ document.getElementById(n),
+ "\'"));
+ add_task(test_with_twice_characters.bind(null,
+ document.getElementById(n),
+ String.fromCharCode(0x2019)));
+ add_task(test_between_single_quote.bind(null,
+ document.getElementById(n)));
+ add_task(test_with_email.bind(null, document.getElementById(n)));
+ add_task(test_with_url.bind(null, document.getElementById(n)));
+ }
+});
+</script>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug1602526.html b/editor/spellchecker/tests/test_bug1602526.html
new file mode 100644
index 0000000000..c0324a8ab5
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug1602526.html
@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>Mozilla bug 1602526</title>
+ <link rel=stylesheet href="/tests/SimpleTest/test.css">
+ <script src="/tests/SimpleTest/EventUtils.js"></script>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/AddTask.js"></script>
+ <script src="/tests/editor/libeditor/tests/spellcheck.js"></script>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1602526">Mozilla Bug 1602526</a>
+<p id="display"></p>
+<div id="content" style="display: none;">
+
+</div>
+
+<div id="contenteditable" contenteditable=true>kkkk&#xf6;kkkk</div>
+
+<script>
+const {onSpellCheck} = SpecialPowers.Cu.import("resource://testing-common/AsyncSpellCheckTestHelper.jsm", {});
+
+SimpleTest.waitForExplicitFinish();
+
+function getEditor() {
+ return SpecialPowers.wrap(window).docShell.editor;
+}
+
+SimpleTest.waitForFocus(async () => {
+ let contenteditable = document.getElementById("contenteditable");
+ let misspeltWords = [];
+ misspeltWords.push("kkkk\u00f6kkkk");
+
+ contenteditable.focus();
+ window.getSelection().collapse(contenteditable.firstChild, contenteditable.firstChild.length);
+
+ synthesizeKey(" ");
+
+ // Run spell checker
+ await new Promise((resolve) => { onSpellCheck(contenteditable, resolve); });
+
+ synthesizeKey("a");
+ synthesizeKey("a");
+ synthesizeKey("a");
+
+ await new Promise((resolve) => { onSpellCheck(contenteditable, resolve); });
+ let editor = getEditor();
+ // isSpellingCheckOk is defined in spellcheck.js
+ // eslint-disable-next-line no-undef
+ ok(isSpellingCheckOk(editor, misspeltWords), "correct word is seleced as misspell");
+
+ SimpleTest.finish();
+});
+</script>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug338427.html b/editor/spellchecker/tests/test_bug338427.html
new file mode 100644
index 0000000000..a316456460
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug338427.html
@@ -0,0 +1,60 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=338427
+-->
+<head>
+ <title>Test for Bug 338427</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=338427">Mozilla Bug 338427</a>
+<p id="display"></p>
+<div id="content">
+<textarea id="editor" lang="testing-XX" spellcheck="true"></textarea>
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 338427 **/
+function init() {
+ var onSpellCheck =
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck;
+ var textarea = document.getElementById("editor");
+ var editor = SpecialPowers.wrap(textarea).editor;
+ var spellchecker = editor.getInlineSpellChecker(true);
+ spellchecker.enableRealTimeSpell = true;
+ textarea.focus();
+
+ onSpellCheck(textarea, function() {
+ var list = spellchecker.spellChecker.GetDictionaryList();
+ ok(list.length > 0, "At least one dictionary should be present");
+
+ var lang = list[0];
+ spellchecker.spellChecker.SetCurrentDictionary(lang);
+
+ onSpellCheck(textarea, function() {
+ try {
+ var dictionary =
+ spellchecker.spellChecker.GetCurrentDictionary();
+ } catch (e) {}
+ is(dictionary, lang, "Unexpected spell check dictionary");
+
+ // This will clear the content preferences and reset "spellchecker.dictionary".
+ spellchecker.spellChecker.SetCurrentDictionary("");
+ SimpleTest.finish();
+ });
+ });
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(init);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug678842.html b/editor/spellchecker/tests/test_bug678842.html
new file mode 100644
index 0000000000..a2b9c8db23
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug678842.html
@@ -0,0 +1,108 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=678842
+-->
+<head>
+ <title>Test for Bug 678842</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=678842">Mozilla Bug 678842</a>
+<p id="display"></p>
+<iframe id="content"></iframe>
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 678842 **/
+SimpleTest.waitForExplicitFinish();
+var content = document.getElementById("content");
+// load a subframe containing an editor with a defined unknown lang. At first
+// load, it will set dictionary to en-US. At second load, it will return current
+// dictionary. So, we can check, dictionary is correctly remembered between
+// loads.
+
+var firstLoad = true;
+var script;
+
+var loadListener = async function(evt) {
+ if (firstLoad) {
+ /* eslint-env mozilla/frame-script */
+ script = SpecialPowers.loadChromeScript(function() {
+ // eslint-disable-next-line mozilla/use-services
+ var 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");
+
+ var hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Install en-GB dictionary.
+ let en_GB = dir.clone();
+ en_GB.append("en-GB");
+ hunspell.addDirectory(en_GB);
+
+ addMessageListener("en_GB-exists", () => en_GB.exists());
+ addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
+ });
+ is(await script.sendQuery("en_GB-exists"), true,
+ "true expected (en-GB directory should exist)");
+ }
+
+ var doc = evt.target.contentDocument;
+ var elem = doc.getElementById("textarea");
+ var editor = SpecialPowers.wrap(elem).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+
+ 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");
+ }
+
+ if (firstLoad) {
+ firstLoad = false;
+
+ // First time around, the dictionary defaults to the locale.
+ is(currentDictonary, "en-US", "unexpected lang " + currentDictonary + " 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";
+ } else {
+ is(currentDictonary, "en-GB", "unexpected lang " + currentDictonary + " 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");
+
+ // This will clear the content preferences and reset "spellchecker.dictionary".
+ spellchecker.SetCurrentDictionary("");
+ SimpleTest.finish();
+ }
+ });
+};
+
+content.addEventListener("load", loadListener);
+
+content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug678842_subframe.html?firstload=true";
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug697981.html b/editor/spellchecker/tests/test_bug697981.html
new file mode 100644
index 0000000000..7dcd1bca3a
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug697981.html
@@ -0,0 +1,138 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=697981
+-->
+<head>
+ <title>Test for Bug 697981</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=697981">Mozilla Bug 697981</a>
+<p id="display"></p>
+</div>
+
+<textarea id="de-DE" lang="de-DE" onfocus="deFocus()">German heute ist ein guter Tag</textarea>
+<textarea id="en-US" lang="en-US" onfocus="enFocus()">Nogoodword today is a nice day</textarea>
+
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+function getMisspelledWords(editor) {
+ return editor.selectionController.getSelection(SpecialPowers.Ci.nsISelectionController.SELECTION_SPELLCHECK).toString();
+}
+
+var elem_de;
+var editor_de;
+var script;
+
+var onSpellCheck =
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck;
+
+/** Test for Bug 697981 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(async function() {
+ /* eslint-env mozilla/frame-script */
+ script = SpecialPowers.loadChromeScript(function() {
+ // eslint-disable-next-line mozilla/use-services
+ var 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");
+
+ var hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Install de-DE dictionary.
+ var de_DE = dir.clone();
+ de_DE.append("de-DE");
+ hunspell.addDirectory(de_DE);
+
+ addMessageListener("de_DE-exists", () => de_DE.exists());
+ addMessageListener("destroy", () => hunspell.removeDirectory(de_DE));
+ });
+ is(await script.sendQuery("de_DE-exists"), true,
+ "true expected (de_DE directory should exist)");
+
+ document.getElementById("de-DE").focus();
+});
+
+function deFocus() {
+ elem_de = document.getElementById("de-DE");
+ editor_de = SpecialPowers.wrap(elem_de).editor;
+ editor_de.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor_de.getInlineSpellChecker(true);
+
+ onSpellCheck(elem_de, function() {
+ var spellchecker = inlineSpellChecker.spellChecker;
+ try {
+ var currentDictonary = spellchecker.GetCurrentDictionary();
+ } catch (e) {}
+
+ // Check that the German dictionary is loaded and that the spell check has worked.
+ is(currentDictonary, "de-DE", "expected de-DE");
+ is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
+
+ // Now focus the other textarea, which requires English spelling.
+ document.getElementById("en-US").focus();
+ });
+}
+
+function enFocus() {
+ var elem_en = document.getElementById("en-US");
+ var editor_en = SpecialPowers.wrap(elem_en).editor;
+ 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) {}
+
+ // Check that the English dictionary is loaded and that the spell check has worked.
+ is(currentDictonary, "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
+ // in the de-DE editor is still the same. After losing focus, no spell check
+ // updates should take place there.
+ is(getMisspelledWords(editor_de), "German", "one misspelled word expected: German");
+
+ // Remove the fake de_DE dictionary again.
+ script.sendAsyncMessage("destroy");
+
+ // Focus again, so the spelling gets updated, but before we need to kill the focus handler.
+ elem_de.onfocus = null;
+ elem_de.blur();
+ elem_de.focus();
+
+ // After removal, the de_DE editor should refresh the spelling with en-US.
+ onSpellCheck(elem_de, function() {
+ spellchecker = inlineSpellChecker.spellChecker;
+ try {
+ currentDictonary = spellchecker.GetCurrentDictionary();
+ } catch (e) {}
+
+ // Check that the default 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");
+
+ SimpleTest.finish();
+ });
+ });
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/spellchecker/tests/test_bug717433.html b/editor/spellchecker/tests/test_bug717433.html
new file mode 100644
index 0000000000..3c55ace128
--- /dev/null
+++ b/editor/spellchecker/tests/test_bug717433.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=717433
+-->
+<head>
+ <title>Test for Bug 717433</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" href="/tests/SimpleTest/test.css">
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717433">Mozilla Bug 717433</a>
+<p id="display"></p>
+<iframe id="content"></iframe>
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 717433 **/
+SimpleTest.waitForExplicitFinish();
+var content = document.getElementById("content");
+// Load a subframe containing an editor with language "en". At first
+// load, it will set the dictionary to en-GB or en-US. We set the other one.
+// At second load, it will return the current dictionary. We can check that the
+// dictionary is correctly remembered between loads.
+
+var firstLoad = true;
+var expected = "";
+var script;
+
+var loadListener = async function(evt) {
+ if (firstLoad) {
+ /* eslint-env mozilla/frame-script */
+ script = SpecialPowers.loadChromeScript(function() {
+ // eslint-disable-next-line mozilla/use-services
+ var 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");
+
+ var hunspell = Cc["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Install en-GB dictionary.
+ var en_GB = dir.clone();
+ en_GB.append("en-GB");
+ hunspell.addDirectory(en_GB);
+
+ addMessageListener("en_GB-exists", () => en_GB.exists());
+ addMessageListener("destroy", () => hunspell.removeDirectory(en_GB));
+ });
+ is(await script.sendQuery("en_GB-exists"), true,
+ "true expected (en-GB directory should exist)");
+ }
+
+ var doc = evt.target.contentDocument;
+ var elem = doc.getElementById("textarea");
+ var editor = SpecialPowers.wrap(elem).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+
+ SpecialPowers.Cu.import(
+ "resource://testing-common/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck(elem, function() {
+ var spellchecker = inlineSpellChecker.spellChecker;
+ try {
+ var currentDictonary = spellchecker.GetCurrentDictionary();
+ } catch (e) {}
+
+ 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");
+ expected = "en-US";
+ } else if (currentDictonary == "en-US") {
+ spellchecker.SetCurrentDictionary("en-GB");
+ 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";
+ } else {
+ is(currentDictonary, 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");
+
+ // This will clear the content preferences and reset "spellchecker.dictionary".
+ spellchecker.SetCurrentDictionary("");
+ SimpleTest.finish();
+ }
+ });
+};
+
+content.addEventListener("load", loadListener);
+
+content.src = "http://mochi.test:8888/tests/editor/spellchecker/tests/bug717433_subframe.html?firstload=true";
+
+</script>
+</pre>
+</body>
+</html>