summaryrefslogtreecommitdiff
path: root/editor/composer/test
diff options
context:
space:
mode:
Diffstat (limited to 'editor/composer/test')
-rw-r--r--editor/composer/test/bug1200533_subframe.html14
-rw-r--r--editor/composer/test/bug1204147_subframe.html11
-rw-r--r--editor/composer/test/bug1204147_subframe2.html9
-rw-r--r--editor/composer/test/bug678842_subframe.html8
-rw-r--r--editor/composer/test/bug717433_subframe.html8
-rw-r--r--editor/composer/test/chrome.ini5
-rw-r--r--editor/composer/test/de-DE/de_DE.aff2
-rw-r--r--editor/composer/test/de-DE/de_DE.dic6
-rw-r--r--editor/composer/test/en-AU/en_AU.aff2
-rw-r--r--editor/composer/test/en-AU/en_AU.dic4
-rw-r--r--editor/composer/test/en-GB/en_GB.aff2
-rw-r--r--editor/composer/test/en-GB/en_GB.dic4
-rw-r--r--editor/composer/test/mochitest.ini40
-rw-r--r--editor/composer/test/test_async_UpdateCurrentDictionary.html75
-rw-r--r--editor/composer/test/test_bug1200533.html139
-rw-r--r--editor/composer/test/test_bug1204147.html112
-rw-r--r--editor/composer/test/test_bug1205983.html137
-rw-r--r--editor/composer/test/test_bug1209414.html150
-rw-r--r--editor/composer/test/test_bug1219928.html76
-rw-r--r--editor/composer/test/test_bug1266815.html82
-rw-r--r--editor/composer/test/test_bug338427.html61
-rw-r--r--editor/composer/test/test_bug348497.html36
-rw-r--r--editor/composer/test/test_bug384147.html204
-rw-r--r--editor/composer/test/test_bug389350.html33
-rw-r--r--editor/composer/test/test_bug434998.xul109
-rw-r--r--editor/composer/test/test_bug519928.html123
-rw-r--r--editor/composer/test/test_bug678842.html105
-rw-r--r--editor/composer/test/test_bug697981.html133
-rw-r--r--editor/composer/test/test_bug717433.html107
-rw-r--r--editor/composer/test/test_bug738440.html37
30 files changed, 1834 insertions, 0 deletions
diff --git a/editor/composer/test/bug1200533_subframe.html b/editor/composer/test/bug1200533_subframe.html
new file mode 100644
index 0000000000..6eaefc266a
--- /dev/null
+++ b/editor/composer/test/bug1200533_subframe.html
@@ -0,0 +1,14 @@
+<!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="ko-not-avail" lang="ko">root en-US, but element ko (which is not installed)</textarea>
+</body>
+</html>
diff --git a/editor/composer/test/bug1204147_subframe.html b/editor/composer/test/bug1204147_subframe.html
new file mode 100644
index 0000000000..a9b1225cd9
--- /dev/null
+++ b/editor/composer/test/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/composer/test/bug1204147_subframe2.html b/editor/composer/test/bug1204147_subframe2.html
new file mode 100644
index 0000000000..935777bd99
--- /dev/null
+++ b/editor/composer/test/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/composer/test/bug678842_subframe.html b/editor/composer/test/bug678842_subframe.html
new file mode 100644
index 0000000000..39d578ee41
--- /dev/null
+++ b/editor/composer/test/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/composer/test/bug717433_subframe.html b/editor/composer/test/bug717433_subframe.html
new file mode 100644
index 0000000000..3c2927e88f
--- /dev/null
+++ b/editor/composer/test/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/composer/test/chrome.ini b/editor/composer/test/chrome.ini
new file mode 100644
index 0000000000..015cad3d5c
--- /dev/null
+++ b/editor/composer/test/chrome.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+skip-if = os == 'android'
+
+[test_bug434998.xul]
+[test_bug1266815.html]
diff --git a/editor/composer/test/de-DE/de_DE.aff b/editor/composer/test/de-DE/de_DE.aff
new file mode 100644
index 0000000000..5dc6896b6d
--- /dev/null
+++ b/editor/composer/test/de-DE/de_DE.aff
@@ -0,0 +1,2 @@
+# Affix file for German English dictionary
+# Fake file, nothing here.
diff --git a/editor/composer/test/de-DE/de_DE.dic b/editor/composer/test/de-DE/de_DE.dic
new file mode 100644
index 0000000000..415c216861
--- /dev/null
+++ b/editor/composer/test/de-DE/de_DE.dic
@@ -0,0 +1,6 @@
+5
+ein
+guter
+heute
+ist
+Tag
diff --git a/editor/composer/test/en-AU/en_AU.aff b/editor/composer/test/en-AU/en_AU.aff
new file mode 100644
index 0000000000..e0c467248d
--- /dev/null
+++ b/editor/composer/test/en-AU/en_AU.aff
@@ -0,0 +1,2 @@
+# Affix file for British English dictionary
+# Fake file, nothing here.
diff --git a/editor/composer/test/en-AU/en_AU.dic b/editor/composer/test/en-AU/en_AU.dic
new file mode 100644
index 0000000000..0a1be725d4
--- /dev/null
+++ b/editor/composer/test/en-AU/en_AU.dic
@@ -0,0 +1,4 @@
+3
+Mary
+Paul
+Peter
diff --git a/editor/composer/test/en-GB/en_GB.aff b/editor/composer/test/en-GB/en_GB.aff
new file mode 100644
index 0000000000..e0c467248d
--- /dev/null
+++ b/editor/composer/test/en-GB/en_GB.aff
@@ -0,0 +1,2 @@
+# Affix file for British English dictionary
+# Fake file, nothing here.
diff --git a/editor/composer/test/en-GB/en_GB.dic b/editor/composer/test/en-GB/en_GB.dic
new file mode 100644
index 0000000000..0a1be725d4
--- /dev/null
+++ b/editor/composer/test/en-GB/en_GB.dic
@@ -0,0 +1,4 @@
+3
+Mary
+Paul
+Peter
diff --git a/editor/composer/test/mochitest.ini b/editor/composer/test/mochitest.ini
new file mode 100644
index 0000000000..832137d603
--- /dev/null
+++ b/editor/composer/test/mochitest.ini
@@ -0,0 +1,40 @@
+[DEFAULT]
+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
+
+[test_async_UpdateCurrentDictionary.html]
+skip-if = os == 'android'
+[test_bug338427.html]
+skip-if = os == 'android'
+[test_bug348497.html]
+[test_bug384147.html]
+[test_bug389350.html]
+skip-if = toolkit == 'android'
+[test_bug519928.html]
+[test_bug678842.html]
+skip-if = os == 'android'
+[test_bug697981.html]
+skip-if = os == 'android'
+[test_bug717433.html]
+skip-if = os == 'android'
+[test_bug738440.html]
+[test_bug1200533.html]
+skip-if = os == 'android'
+[test_bug1204147.html]
+skip-if = os == 'android'
+[test_bug1205983.html]
+skip-if = os == 'android'
+[test_bug1209414.html]
+skip-if = os == 'android'
+[test_bug1219928.html]
+skip-if = e10s || os == 'android'
diff --git a/editor/composer/test/test_async_UpdateCurrentDictionary.html b/editor/composer/test/test_async_UpdateCurrentDictionary.html
new file mode 100644
index 0000000000..53d9ff307c
--- /dev/null
+++ b/editor/composer/test/test_async_UpdateCurrentDictionary.html
@@ -0,0 +1,75 @@
+<!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;version=1.8">
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(start);
+
+function start() {
+ var textarea = document.getElementById("editor");
+ textarea.focus();
+
+ SpecialPowers.Cu.import("resource://gre/modules/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/composer/test/test_bug1200533.html b/editor/composer/test/test_bug1200533.html
new file mode 100644
index 0000000000..310b8d7cf5
--- /dev/null
+++ b/editor/composer/test/test_bug1200533.html
@@ -0,0 +1,139 @@
+<!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-*.
+ [ "en-ZA-not-avail", "", "*" ],
+ [ "en-generic", "", "*" ],
+ // 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 script;
+
+var loadListener = function(evt) {
+ if (loadCount == 0) {
+ script = SpecialPowers.loadChromeScript(function() {
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+ dir.append("tests");
+ dir.append("editor");
+ dir.append("composer");
+ dir.append("test");
+
+ var hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
+ .getService(Components.interfaces.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 = script.sendSyncMessage("check-existence")[0][0];
+ 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).QueryInterface(SpecialPowers.Ci.nsIDOMNSEditableElement).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+
+ SpecialPowers.Cu.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck(elem, function () {
+ var spellchecker = inlineSpellChecker.spellChecker;
+ try {
+ var dict = spellchecker.GetCurrentDictionary();
+ } catch(e) {}
+
+ if (tests[loadCount][2] != "*") {
+ is (dict, tests[loadCount][2], "expected " + tests[loadCount][2]);
+ } 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++;
+ if (loadCount < tests.length) {
+ // Load the iframe again.
+ content.src = 'http://mochi.test:8888/tests/editor/composer/test/bug1200533_subframe.html?firstload=false';
+ } else {
+ // Remove the fake dictionaries again, since it's otherwise picked up by later tests.
+ script.sendSyncMessage("destroy");
+
+ SimpleTest.finish();
+ }
+ });
+
+}
+
+content.addEventListener('load', loadListener, false);
+
+content.src = 'http://mochi.test:8888/tests/editor/composer/test/bug1200533_subframe.html?firstload=true';
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/composer/test/test_bug1204147.html b/editor/composer/test/test_bug1204147.html
new file mode 100644
index 0000000000..d7dd904740
--- /dev/null
+++ b/editor/composer/test/test_bug1204147.html
@@ -0,0 +1,112 @@
+<!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 = function(evt) {
+ if (firstLoad) {
+ script = SpecialPowers.loadChromeScript(function() {
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+ dir.append("tests");
+ dir.append("editor");
+ dir.append("composer");
+ dir.append("test");
+
+ var hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
+ .getService(Components.interfaces.mozISpellCheckingEngine);
+
+ // Install en-GB dictionary.
+ 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(script.sendSyncMessage("en_GB-exists")[0][0], 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).QueryInterface(SpecialPowers.Ci.nsIDOMNSEditableElement).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+
+ SpecialPowers.Cu.import("resource://gre/modules/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/composer/test/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, false);
+
+ // Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
+ script.sendSyncMessage("destroy");
+
+ // Reset the preference, so the last value we set doesn't collide with the next test.
+ SimpleTest.finish();
+ }
+ });
+}
+
+content.addEventListener('load', loadListener, false);
+
+content.src = 'http://mochi.test:8888/tests/editor/composer/test/bug1204147_subframe.html?firstload=true';
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/composer/test/test_bug1205983.html b/editor/composer/test/test_bug1205983.html
new file mode 100644
index 0000000000..139f6fc3c5
--- /dev/null
+++ b/editor/composer/test/test_bug1205983.html
@@ -0,0 +1,137 @@
+<!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://gre/modules/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck;
+
+/** Test for Bug 1205983 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ script = SpecialPowers.loadChromeScript(function() {
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+ dir.append("tests");
+ dir.append("editor");
+ dir.append("composer");
+ dir.append("test");
+
+ var hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
+ .getService(Components.interfaces.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(script.sendSyncMessage("de_DE-exists")[0][0], 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 Ci = SpecialPowers.Ci;
+ var editingSession = SpecialPowers.wrap(window)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIEditingSession);
+ 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)
+ .QueryInterface(SpecialPowers.Ci.nsIDOMNSEditableElement)
+ .editor;
+ editor_en.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor_en.getInlineSpellChecker(true);
+
+ onSpellCheck(elem_en, function () {
+ var spellchecker = inlineSpellChecker.spellChecker;
+ 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.sendSyncMessage("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 sel = selcon_de.getSelection(selcon_de.SELECTION_SPELLCHECK);
+ is(sel.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/composer/test/test_bug1209414.html b/editor/composer/test/test_bug1209414.html
new file mode 100644
index 0000000000..bce1bb313f
--- /dev/null
+++ b/editor/composer/test/test_bug1209414.html
@@ -0,0 +1,150 @@
+<!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://gre/modules/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck;
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ script = SpecialPowers.loadChromeScript(function() {
+ const Ci = Components.interfaces;
+ var chromeWin = browserElement.ownerDocument.defaultView
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShellTreeItem)
+ .rootTreeItem
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIDOMWindow)
+ .QueryInterface(Ci.nsIDOMChromeWindow);
+ var contextMenu = chromeWin.document.getElementById("contentAreaContextMenu");
+ contextMenu.addEventListener("popupshown",
+ () => sendAsyncMessage("popupshown"), false);
+
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Ci.nsIProperties)
+ .get("CurWorkD", Ci.nsIFile);
+ dir.append("tests");
+ dir.append("editor");
+ dir.append("composer");
+ dir.append("test");
+
+ var hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
+ .getService(Ci.mozISpellCheckingEngine);
+
+ // Install de-DE dictionary.
+ 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(script.sendSyncMessage("contextMenu-not-null")[0][0], true,
+ "Got context menu XUL");
+ is(script.sendSyncMessage("de_DE-exists")[0][0], true,
+ "true expected (de_DE directory should exist)");
+ script.addMessageListener("popupshown", handlePopup);
+
+ elem_de = document.getElementById('de-DE');
+ editor_de = SpecialPowers.wrap(elem_de)
+ .QueryInterface(Ci.nsIDOMNSEditableElement).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");
+ 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);
+ });
+ });
+});
+
+function handlePopup() {
+ var state = script.sendSyncMessage("hidepopup")[0][0];
+ is(state, "open", "checking if popup is open");
+
+ onSpellCheck(elem_de, function () {
+ var inlineSpellChecker = editor_de.getInlineSpellChecker(true);
+ var spellchecker = inlineSpellChecker.spellChecker;
+ 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_de), "heute" + "ist" + "ein" + "guter", "some misspelled words expected: heute ist ein guter");
+
+ // Remove the fake de_DE dictionary again.
+ script.sendSyncMessage("destroy");
+
+ // This will clear the content preferences and reset "spellchecker.dictionary".
+ spellchecker.SetCurrentDictionary("");
+ SimpleTest.finish();
+ });
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/composer/test/test_bug1219928.html b/editor/composer/test/test_bug1219928.html
new file mode 100644
index 0000000000..2f646f00f3
--- /dev/null
+++ b/editor/composer/test/test_bug1219928.html
@@ -0,0 +1,76 @@
+<!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() {
+ SpecialPowers.Cu.import("resource://gre/modules/AsyncSpellCheckTestHelper.jsm",
+ window);
+
+ var elem = document.getElementById('en-US');
+ elem.focus();
+
+ onSpellCheck(elem, function () {
+ var Ci = SpecialPowers.Ci;
+ var editingSession = SpecialPowers.wrap(window)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIEditingSession);
+ 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.Cc['@mozilla.org/editor/editorspellchecker;1']
+ .createInstance(Ci.nsIEditorSpellCheck);
+ var filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
+ spellchecker.setFilter(SpecialPowers.Cc[filterContractId]
+ .createInstance(Ci.nsITextServicesFilter));
+ 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/composer/test/test_bug1266815.html b/editor/composer/test/test_bug1266815.html
new file mode 100644
index 0000000000..a2ab0b0488
--- /dev/null
+++ b/editor/composer/test/test_bug1266815.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SpawnTask.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<p id="display"></p>
+<script type="text/javascript">
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+const Cu = SpecialPowers.Cu;
+
+const {XPCOMUtils} = Cu.import("resource://gre/modules/XPCOMUtils.jsm", {});
+
+const HELPERAPP_DIALOG_CID =
+ SpecialPowers.wrap(SpecialPowers.Components)
+ .ID(Cc["@mozilla.org/helperapplauncherdialog;1"].number);
+const HELPERAPP_DIALOG_CONTRACT_ID = "@mozilla.org/helperapplauncherdialog;1";
+const MOCK_HELPERAPP_DIALOG_CID =
+ SpecialPowers.wrap(SpecialPowers.Components)
+ .ID("{391832c8-5232-4676-b838-cc8ad373f3d8}");
+
+var registrar = SpecialPowers.wrap(Components).manager
+ .QueryInterface(Ci.nsIComponentRegistrar);
+
+var helperAppDlgPromise = new Promise(function(resolve) {
+ var mockHelperAppService;
+
+ function HelperAppLauncherDialog() {
+ }
+
+ HelperAppLauncherDialog.prototype = {
+ show: function(aLauncher, aWindowContext, aReason) {
+ ok(true, "Whether showing Dialog");
+ resolve();
+ registrar.unregisterFactory(MOCK_HELPERAPP_DIALOG_CID,
+ mockHelperAppService);
+ },
+ QueryInterface: XPCOMUtils.generateQI([Ci.nsIHelperAppLauncherDialog])
+ };
+
+ mockHelperAppService = XPCOMUtils._getFactory(HelperAppLauncherDialog);
+ registrar.registerFactory(MOCK_HELPERAPP_DIALOG_CID, "",
+ HELPERAPP_DIALOG_CONTRACT_ID,
+ mockHelperAppService);
+});
+
+add_task(function*() {
+ let promise = new Promise(function(resolve) {
+ let iframe = document.createElement("iframe");
+ iframe.onload = function() {
+ is(iframe.contentDocument.getElementById("edit").innerText, "abc",
+ "load iframe source");
+ resolve();
+ };
+ iframe.id = "testframe";
+ iframe.src = "data:text/html,<div id=edit contenteditable=true>abc</div>";
+ document.body.appendChild(iframe);
+ });
+
+ yield promise;
+
+ let iframe = document.getElementById("testframe");
+ let docShell = SpecialPowers.wrap(iframe.contentWindow)
+ .QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell);
+
+ ok(docShell.hasEditingSession, "Should have editing session");
+
+ document.getElementById("testframe").src =
+ "data:application/octet-stream,TESTCONTENT";
+
+ yield helperAppDlgPromise;
+
+ ok(docShell.hasEditingSession, "Should have editing session");
+});
+</script>
+</body>
+</html>
diff --git a/editor/composer/test/test_bug338427.html b/editor/composer/test/test_bug338427.html
new file mode 100644
index 0000000000..f16194b3d3
--- /dev/null
+++ b/editor/composer/test/test_bug338427.html
@@ -0,0 +1,61 @@
+<!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://gre/modules/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 = {}, count = {};
+ spellchecker.spellChecker.GetDictionaryList(list, count);
+ ok(count.value > 0, "At least one dictionary should be present");
+
+ var lang = list.value[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/composer/test/test_bug348497.html b/editor/composer/test/test_bug348497.html
new file mode 100644
index 0000000000..9483b727a8
--- /dev/null
+++ b/editor/composer/test/test_bug348497.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=348497
+-->
+<head>
+ <title>Test for Bug 348497</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=348497">Mozilla Bug 348497</a>
+<p id="display"></p>
+<div id="content">
+ This page should not crash Mozilla<br>
+ <iframe id="testIframe"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 348497 **/
+function doe() {
+ document.getElementById('testIframe').style.display = 'block';
+ document.getElementById('testIframe').contentDocument.designMode = 'on';
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(doe);
+addLoadEvent(function() { ok(true, "enabling designmode on an iframe onload does not crash Mozilla")});
+addLoadEvent(SimpleTest.finish);
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/editor/composer/test/test_bug384147.html b/editor/composer/test/test_bug384147.html
new file mode 100644
index 0000000000..35f0e533ed
--- /dev/null
+++ b/editor/composer/test/test_bug384147.html
@@ -0,0 +1,204 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=384147
+-->
+<head>
+ <title>Test for Bug 384147</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=384147">Mozilla Bug 384147</a>
+<p id="display"></p>
+<div id="content" style="display: block">
+<div contentEditable id="editor"></div>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript;version=1.7">
+
+/** Test for Bug 384147 **/
+
+SimpleTest.waitForExplicitFinish();
+
+var editor = document.getElementById("editor");
+
+editor.innerHTML = "<ol><li>Item 1</li><li>Item 2</li><ol><li>Item 3</li></ol></ol><ul><li>Item 4</li><li>Item 5</li></ul>";
+editor.focus();
+
+// If executed directly, a race condition exists that will cause execCommand
+// to fail occasionally (but often). Defer test execution to page load.
+addLoadEvent(function() {
+
+ var sel = window.getSelection();
+
+ // Test the effect that the tab key has on list items. Each test is
+ // documented with the initial state of the list on the left, and the
+ // expected state of the list on the right. {\t} indicates the list item
+ // that will be indented. {\st} indicates that a shift-tab will be simulated
+ // on that list item, outdenting it.
+ //
+ // Note: any test failing will likely result in all following tests failing
+ // as well, since each test depends on the document being in a given state.
+ // Unfortunately, due to the problems getting document focus and key events
+ // to fire consistently, it's difficult to reset state between tests.
+ // If there are test failures here, only debug the first test failure.
+
+ // *** test 1 ***
+ // 1. Item 1 1. Item 1
+ // 2. {\t}Item 2 1. Item 2
+ // 1. Item 3 2. Item 3
+ // * Item 4 * Item 4
+ // * Item 5 * Item 5
+ sel.removeAllRanges();
+ sel.selectAllChildren(editor.getElementsByTagName("li")[1]);
+ document.execCommand("indent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><li>Item 3</li></ol></ol><ul><li>Item 4</li><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 1");
+
+ // *** test 2 ***
+ // 1. Item 1 1. Item 1
+ // 1. Item 2 1. Item 2
+ // 2. {\t}Item 3 1. Item 3
+ // * Item 4 * Item 4
+ // * Item 5 * Item 5
+ sel.removeAllRanges();
+ sel.selectAllChildren(editor.getElementsByTagName("li")[2]);
+ document.execCommand("indent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><ol><li>Item 3</li></ol></ol></ol><ul><li>Item 4</li><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 2");
+
+ // *** test 3 ***
+ // 1. Item 1 1. Item 1
+ // 1. Item 2 1. Item 2
+ // 1. {\st}Item 3 2. Item 3
+ // * Item 4 * Item 4
+ // * Item 5 * Item 5
+ document.execCommand("outdent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><li>Item 3</li></ol></ol><ul><li>Item 4</li><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 3");
+
+ // *** test 4 ***
+ // 1. Item 1 1. Item 1
+ // 1. Item 2 1. Item 2
+ // 2. {\st}Item 3 2. Item 3
+ // * Item 4 * Item 4
+ // * Item 5 * Item 5
+ document.execCommand("outdent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li></ol><li>Item 3</li></ol><ul><li>Item 4</li><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 4");
+
+ // *** test 5 ***
+ // 1. Item 1 1. Item 1
+ // 1. {\st}Item 2 2. Item 2
+ // 2. Item 3 3. Item 3
+ // * Item 4 * Item 4
+ // * Item 5 * Item 5
+ sel.removeAllRanges();
+ sel.selectAllChildren(editor.getElementsByTagName("li")[1]);
+ document.execCommand("outdent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><li>Item 2</li><li>Item 3</li></ol><ul><li>Item 4</li><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 5");
+
+ // *** test 6 ***
+ // 1. Item 1 1. Item 1
+ // 2. {\t}Item 2 1. Item 2
+ // 3. Item 3 2. Item 3
+ // * Item 4 * Item 4
+ // * Item 5 * Item 5
+ document.execCommand("indent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li></ol><li>Item 3</li></ol><ul><li>Item 4</li><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 6");
+
+ // *** test 7 ***
+ // 1. Item 1 1. Item 1
+ // 1. Item 2 1. Item 2
+ // 2. {\t}Item 3 2. Item 3
+ // * Item 4 * Item 4
+ // * Item 5 * Item 5
+ sel.removeAllRanges();
+ sel.selectAllChildren(editor.getElementsByTagName("li")[2]);
+ document.execCommand("indent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><li>Item 3</li></ol></ol><ul><li>Item 4</li><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 7");
+
+ // That covers the basics of merging lists on indent and outdent.
+ // We also want to check that ul / ol lists won't be merged together,
+ // since they're different types of lists.
+ // *** test 8 ***
+ // 1. Item 1 1. Item 1
+ // 1. Item 2 1. Item 2
+ // 2. Item 3 2. Item 3
+ // * {\t}Item 4 * Item 4
+ // * Item 5 * Item 5
+ sel.removeAllRanges();
+ sel.selectAllChildren(editor.getElementsByTagName("li")[3]);
+ document.execCommand("indent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><li>Item 3</li></ol></ol><ul><ul><li>Item 4</li></ul><li>Item 5</li></ul>",
+ "html output doesn't match expected value in test 8");
+
+ // Better test merging with <ul> rather than <ol> too.
+ // *** test 9 ***
+ // 1. Item 1 1. Item 1
+ // 1. Item 2 1. Item 2
+ // 2. Item 3 2. Item 3
+ // * Item 4 * Item 4
+ // * {\t}Item 5 * Item 5
+ sel.removeAllRanges();
+ sel.selectAllChildren(editor.getElementsByTagName("li")[4]);
+ document.execCommand("indent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><li>Item 3</li></ol></ol><ul><ul><li>Item 4</li><li>Item 5</li></ul></ul>",
+ "html output doesn't match expected value in test 9");
+
+ // Same test as test 8, but with outdent rather than indent.
+ // *** test 10 ***
+ // 1. Item 1 1. Item 1
+ // 1. Item 2 1. Item 2
+ // 2. Item 3 2. Item 3
+ // * {\st}Item 4 * Item 4
+ // * Item 5 * Item 5
+ sel.removeAllRanges();
+ sel.selectAllChildren(editor.getElementsByTagName("li")[3]);
+ document.execCommand("outdent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><li>Item 3</li></ol></ol><ul><li>Item 4</li><ul><li>Item 5</li></ul></ul>",
+ "html output doesn't match expected value in test 10");
+
+ // Test indenting multiple items at once. Hold down "shift" and select
+ // upwards to get all the <ol> items and the first <ul> item.
+ // *** test 11 ***
+ // 1. Item 1 1. Item 1
+ // 1. {\t}Item 2 1. Item 2
+ // 2. {\t}Item 3 2. Item 3
+ // * {\t}Item 4 * Item 4
+ // * Item 5 * Item 5
+ sel.removeAllRanges();
+ var range = document.createRange();
+ range.setStart(editor.getElementsByTagName("li")[1], 0);
+ range.setEnd(editor.getElementsByTagName("li")[3], editor.getElementsByTagName("li")[3].childNodes.length);
+ sel.addRange(range);
+ document.execCommand("indent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><ol><li>Item 2</li><li>Item 3</li></ol></ol></ol><ul><ul><li>Item 4</li><li>Item 5</li></ul></ul>",
+ "html output doesn't match expected value in test 11");
+
+ // Test outdenting multiple items at once. Selection is already ready...
+ // *** test 12 ***
+ // 1. Item 1 1. Item 1
+ // 1. {\st}Item 2 1. Item 2
+ // 2. {\st}Item 3 2. Item 3
+ // * {\st}Item 4 * Item 4
+ // * Item 5 * Item 5
+ document.execCommand("outdent", false, null);
+ ok(editor.innerHTML == "<ol><li>Item 1</li><ol><li>Item 2</li><li>Item 3</li></ol></ol><ul><li>Item 4</li><ul><li>Item 5</li></ul></ul>",
+ "html output doesn't match expected value in test 12");
+
+ SimpleTest.finish();
+});
+
+
+
+</script>
+</pre>
+</body>
+</html>
+
diff --git a/editor/composer/test/test_bug389350.html b/editor/composer/test/test_bug389350.html
new file mode 100644
index 0000000000..bf1d514add
--- /dev/null
+++ b/editor/composer/test/test_bug389350.html
@@ -0,0 +1,33 @@
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=389350
+-->
+<head>
+<title>Test for Bug 389350</title>
+<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+
+<script type="text/javascript">
+
+function runTest() {
+ var e = document.getElementById("edit");
+ e.contentDocument.designMode='on';
+ e.style.display='block';
+ e.focus();
+ sendString('abc');
+ var expected = "<head></head><body>abc</body>";
+ var result = e.contentDocument.documentElement.innerHTML;
+ is(result, expected, "iframe with designmode on had incorrect content");
+ SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(runTest);
+</script>
+
+</head>
+<body id="body">
+<iframe id="edit" width="200" height="100" style="display: none;" src="">
+</body>
+</html>
diff --git a/editor/composer/test/test_bug434998.xul b/editor/composer/test/test_bug434998.xul
new file mode 100644
index 0000000000..4a384ac1c3
--- /dev/null
+++ b/editor/composer/test/test_bug434998.xul
@@ -0,0 +1,109 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin"
+ type="text/css"?>
+<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
+ type="text/css"?>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=434998
+-->
+<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="Mozilla Bug 434998" onload="runTest();">
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
+ <script type="application/javascript"
+ src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"/>
+
+ <body xmlns="http://www.w3.org/1999/xhtml">
+ <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=434998"
+ target="_blank">Mozilla Bug 434998</a>
+ <p/>
+ <editor xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="editor"
+ type="content-primary"
+ editortype="html"
+ style="width: 400px; height: 100px; border: thin solid black"/>
+ <p/>
+ <pre id="test">
+ </pre>
+ </body>
+ <script class="testbody" type="application/javascript">
+ <![CDATA[
+
+ SimpleTest.waitForExplicitFinish();
+
+ function EditorContentListener(aEditor)
+ {
+ this.init(aEditor);
+ }
+
+ EditorContentListener.prototype = {
+ init : function(aEditor)
+ {
+ this.mEditor = aEditor;
+ },
+
+ QueryInterface : function(aIID)
+ {
+ if (aIID.equals(Components.interfaces.nsIWebProgressListener) ||
+ aIID.equals(Components.interfaces.nsISupportsWeakReference) ||
+ aIID.equals(Components.interfaces.nsISupports))
+ return this;
+ throw Components.results.NS_NOINTERFACE;
+ },
+
+ onStateChange : function(aWebProgress, aRequest, aStateFlags, aStatus)
+ {
+ if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP)
+ {
+ var editor = this.mEditor.getEditor(this.mEditor.contentWindow);
+ if (editor) {
+ // Should not throw
+ var threw = false;
+ try {
+ this.mEditor.contentDocument.execCommand("bold", false, null);
+ } catch (e) {
+ threw = true;
+ }
+ ok(!threw, "The execCommand API should work on <xul:editor>");
+ progress.removeProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+ SimpleTest.finish();
+ }
+ }
+ },
+
+
+ onProgressChange : function(aWebProgress, aRequest,
+ aCurSelfProgress, aMaxSelfProgress,
+ aCurTotalProgress, aMaxTotalProgress)
+ {
+ },
+
+ onLocationChange : function(aWebProgress, aRequest, aLocation, aFlags)
+ {
+ },
+
+ onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage)
+ {
+ },
+
+ onSecurityChange : function(aWebProgress, aRequest, aState)
+ {
+ },
+
+ mEditor: null
+ };
+
+ var progress, progressListener;
+
+ function runTest() {
+ var newEditorElement = document.getElementById("editor");
+ newEditorElement.makeEditable("html", true);
+ var docShell = newEditorElement.boxObject.docShell;
+ progress = docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebProgress);
+ progressListener = new EditorContentListener(newEditorElement);
+ progress.addProgressListener(progressListener, Components.interfaces.nsIWebProgress.NOTIFY_ALL);
+ newEditorElement.setAttribute("src", "data:text/html,");
+ }
+]]>
+</script>
+</window>
diff --git a/editor/composer/test/test_bug519928.html b/editor/composer/test/test_bug519928.html
new file mode 100644
index 0000000000..3b1a9ba175
--- /dev/null
+++ b/editor/composer/test/test_bug519928.html
@@ -0,0 +1,123 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=519928
+-->
+<head>
+ <title>Test for Bug 519928</title>
+ <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=519928">Mozilla Bug 519928</a>
+<p id="display"></p>
+<div id="content">
+<iframe id="load-frame"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+var iframe = document.getElementById("load-frame");
+
+function enableJS() { allowJS(true, iframe); }
+function disableJS() { allowJS(false, iframe); }
+function allowJS(allow, frame) {
+ SpecialPowers.wrap(frame.contentWindow)
+ .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
+ .getInterface(SpecialPowers.Ci.nsIWebNavigation)
+ .QueryInterface(SpecialPowers.Ci.nsIDocShell)
+ .allowJavascript = allow;
+}
+
+function expectJSAllowed(allowed, testCondition, callback) {
+ window.ICanRunMyJS = false;
+ var self_ = window;
+ testCondition();
+
+ var doc = iframe.contentDocument;
+ doc.body.innerHTML = "<iframe></iframe>";
+ var innerFrame = doc.querySelector("iframe");
+ innerFrame.addEventListener("load", function() {
+ innerFrame.removeEventListener("load", arguments.callee, false);
+
+ var msg = "The inner iframe should" + (allowed ? "" : " not") + " be able to run Javascript";
+ is(self_.ICanRunMyJS, allowed, msg);
+ callback();
+ }, false);
+ var iframeSrc = "data:text/html,<script>parent.parent.ICanRunMyJS = true;</scr" + "ipt>";
+ innerFrame.src = iframeSrc;
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+ var enterDesignMode = function() { document.designMode = "on"; };
+ var leaveDesignMode = function() { document.designMode = "off"; };
+ expectJSAllowed(false, disableJS, function() {
+ expectJSAllowed(true, enableJS, function() {
+ expectJSAllowed(true, enterDesignMode, function() {
+ expectJSAllowed(true, leaveDesignMode, function() {
+ expectJSAllowed(false, disableJS, function() {
+ expectJSAllowed(false, enterDesignMode, function() {
+ expectJSAllowed(false, leaveDesignMode, function() {
+ expectJSAllowed(true, enableJS, function() {
+ enterDesignMode = function() { iframe.contentDocument.designMode = "on"; };
+ leaveDesignMode = function() { iframe.contentDocument.designMode = "off"; };
+ expectJSAllowed(false, disableJS, function() {
+ expectJSAllowed(true, enableJS, function() {
+ expectJSAllowed(true, enterDesignMode, function() {
+ expectJSAllowed(true, leaveDesignMode, function() {
+ expectJSAllowed(false, disableJS, function() {
+ expectJSAllowed(false, enterDesignMode, function() {
+ expectJSAllowed(false, leaveDesignMode, function() {
+ expectJSAllowed(true, enableJS, function() {
+ testDocumentDisabledJS();
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+ });
+});
+
+function testDocumentDisabledJS() {
+ window.ICanRunMyJS = false;
+ var self_ = window;
+ // Ensure design modes are disabled
+ document.designMode = "off";
+ iframe.contentDocument.designMode = "off";
+
+ // Javascript enabled on the main iframe
+ enableJS();
+
+ var doc = iframe.contentDocument;
+ doc.body.innerHTML = "<iframe></iframe>";
+ var innerFrame = doc.querySelector("iframe");
+
+ // Javascript disabled on the innerFrame.
+ allowJS(false, innerFrame);
+
+ innerFrame.addEventListener("load", function() {
+ innerFrame.removeEventListener("load", arguments.callee, false);
+
+ var msg = "The inner iframe should not be able to run Javascript";
+ is(self_.ICanRunMyJS, false, msg);
+ SimpleTest.finish();
+ }, false);
+ var iframeSrc = "data:text/html,<script>parent.parent.ICanRunMyJS = true;</scr" + "ipt>";
+ innerFrame.src = iframeSrc;
+}
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/composer/test/test_bug678842.html b/editor/composer/test/test_bug678842.html
new file mode 100644
index 0000000000..226b25ee20
--- /dev/null
+++ b/editor/composer/test/test_bug678842.html
@@ -0,0 +1,105 @@
+<!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 = function(evt) {
+ if (firstLoad) {
+ script = SpecialPowers.loadChromeScript(function() {
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+ dir.append("tests");
+ dir.append("editor");
+ dir.append("composer");
+ dir.append("test");
+
+ var hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
+ .getService(Components.interfaces.mozISpellCheckingEngine);
+
+ // Install en-GB dictionary.
+ 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(script.sendSyncMessage("en_GB-exists")[0][0], true,
+ "true expected (en-GB directory should exist)");
+ }
+
+ var doc = evt.target.contentDocument;
+ var elem = doc.getElementById('textarea');
+ var editor = SpecialPowers.wrap(elem).QueryInterface(SpecialPowers.Ci.nsIDOMNSEditableElement).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+
+ SpecialPowers.Cu.import("resource://gre/modules/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/composer/test/bug678842_subframe.html?firstload=false';
+ } else {
+ is (currentDictonary, "en-GB", "unexpected lang " + currentDictonary + " instead of en-GB");
+ content.removeEventListener('load', loadListener, false);
+
+ // Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
+ script.sendSyncMessage("destroy");
+
+ // This will clear the content preferences and reset "spellchecker.dictionary".
+ spellchecker.SetCurrentDictionary("");
+ SimpleTest.finish();
+ }
+ });
+}
+
+content.addEventListener('load', loadListener, false);
+
+content.src = 'http://mochi.test:8888/tests/editor/composer/test/bug678842_subframe.html?firstload=true';
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/composer/test/test_bug697981.html b/editor/composer/test/test_bug697981.html
new file mode 100644
index 0000000000..f9417acb05
--- /dev/null
+++ b/editor/composer/test/test_bug697981.html
@@ -0,0 +1,133 @@
+<!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://gre/modules/AsyncSpellCheckTestHelper.jsm")
+ .onSpellCheck;
+
+/** Test for Bug 697981 **/
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(function() {
+ script = SpecialPowers.loadChromeScript(function() {
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+ dir.append("tests");
+ dir.append("editor");
+ dir.append("composer");
+ dir.append("test");
+
+ var hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
+ .getService(Components.interfaces.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(script.sendSyncMessage("de_DE-exists")[0][0], 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).QueryInterface(SpecialPowers.Ci.nsIDOMNSEditableElement).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).QueryInterface(SpecialPowers.Ci.nsIDOMNSEditableElement).editor;
+ editor_en.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor_en.getInlineSpellChecker(true);
+
+ onSpellCheck(elem_en, function () {
+ var spellchecker = inlineSpellChecker.spellChecker;
+ 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.sendSyncMessage("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");
+ 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/composer/test/test_bug717433.html b/editor/composer/test/test_bug717433.html
new file mode 100644
index 0000000000..59ad9b247c
--- /dev/null
+++ b/editor/composer/test/test_bug717433.html
@@ -0,0 +1,107 @@
+<!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 = function(evt) {
+
+ if (firstLoad) {
+ script = SpecialPowers.loadChromeScript(function() {
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .getService(Components.interfaces.nsIProperties)
+ .get("CurWorkD", Components.interfaces.nsIFile);
+ dir.append("tests");
+ dir.append("editor");
+ dir.append("composer");
+ dir.append("test");
+
+ var hunspell = Components.classes["@mozilla.org/spellchecker/engine;1"]
+ .getService(Components.interfaces.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(script.sendSyncMessage("en_GB-exists")[0][0], true,
+ "true expected (en-GB directory should exist)");
+ }
+
+ var doc = evt.target.contentDocument;
+ var elem = doc.getElementById('textarea');
+ var editor = SpecialPowers.wrap(elem).QueryInterface(SpecialPowers.Ci.nsIDOMNSEditableElement).editor;
+ editor.setSpellcheckUserOverride(true);
+ var inlineSpellChecker = editor.getInlineSpellChecker(true);
+
+ SpecialPowers.Cu.import("resource://gre/modules/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/composer/test/bug717433_subframe.html?firstload=false';
+ } else {
+ is(currentDictonary, expected, expected + " expected");
+ content.removeEventListener('load', loadListener, false);
+
+ // Remove the fake en-GB dictionary again, since it's otherwise picked up by later tests.
+ script.sendSyncMessage("destroy");
+
+ // This will clear the content preferences and reset "spellchecker.dictionary".
+ spellchecker.SetCurrentDictionary("");
+ SimpleTest.finish();
+ }
+ });
+}
+
+content.addEventListener('load', loadListener, false);
+
+content.src = 'http://mochi.test:8888/tests/editor/composer/test/bug717433_subframe.html?firstload=true';
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/editor/composer/test/test_bug738440.html b/editor/composer/test/test_bug738440.html
new file mode 100644
index 0000000000..a021906cfc
--- /dev/null
+++ b/editor/composer/test/test_bug738440.html
@@ -0,0 +1,37 @@
+<!doctype html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=738440
+-->
+<title>Test for Bug 738440</title>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<link rel="stylesheet" href="/tests/SimpleTest/test.css" />
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=738440">Mozilla Bug 738440</a>
+<div contenteditable></div>
+<script>
+
+/** Test for Bug 738440 **/
+document.execCommand("stylewithcss", false, "true");
+is(document.queryCommandState("stylewithcss"), true,
+ "setting stylewithcss to true should cause its state to be true");
+is(document.queryCommandState("usecss"), false,
+ "usecss state should always be false");
+
+document.execCommand("stylewithcss", false, "false");
+is(document.queryCommandState("stylewithcss"), false,
+ "setting stylewithcss to false should cause its state to be false");
+is(document.queryCommandState("usecss"), false,
+ "usecss state should always be false");
+
+document.execCommand("usecss", false, "true");
+is(document.queryCommandState("stylewithcss"), false,
+ "setting usecss to true should cause stylewithcss state to be false");
+is(document.queryCommandState("usecss"), false,
+ "usecss state should always be false");
+
+document.execCommand("usecss", false, "false");
+is(document.queryCommandState("stylewithcss"), true,
+ "setting usecss to false should cause stylewithcss state to be true");
+is(document.queryCommandState("usecss"), false,
+ "usecss state should always be false");
+
+</script>