Bug 1874684 - Part 10: Replace BigInt with Int128 in RoundNumberToIncrement. r=mgaudet
[gecko.git] / editor / AsyncSpellCheckTestHelper.sys.mjs
blob748e54df66037c5628fafdb0c6b256610ceca077
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2  * License, v. 2.0. If a copy of the MPL was not distributed with this
3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 const SPELL_CHECK_ENDED_TOPIC = "inlineSpellChecker-spellCheck-ended";
6 const SPELL_CHECK_STARTED_TOPIC = "inlineSpellChecker-spellCheck-started";
8 const CP = Cc["@mozilla.org/content-pref/service;1"].getService(
9   Ci.nsIContentPrefService2
12 /**
13  * Waits until spell checking has stopped on the given element.
14  *
15  * When a spell check is pending, this waits indefinitely until the spell check
16  * ends.  When a spell check is not pending, it waits a small number of turns of
17  * the event loop: if a spell check begins, it resumes waiting indefinitely for
18  * the end, and otherwise it stops waiting and calls the callback.
19  *
20  * This this can therefore trap spell checks that have not started at the time
21  * of calling, spell checks that have already started, multiple consecutive
22  * spell checks, and the absence of spell checks altogether.
23  *
24  * @param editableElement  The element being spell checked.
25  * @param callback         Called when spell check has completed or enough turns
26  *                         of the event loop have passed to determine it has not
27  *                         started.
28  */
29 export function maybeOnSpellCheck(editableElement, callback) {
30   let editor = editableElement.editor;
31   if (!editor) {
32     let win = editableElement.ownerGlobal;
33     editor = win.docShell.editingSession.getEditorForWindow(win);
34   }
35   if (!editor) {
36     throw new Error("Unable to find editor for element " + editableElement);
37   }
39   try {
40     // False is important here.  Pass false so that the inline spell checker
41     // isn't created if it doesn't already exist.
42     var isc = editor.getInlineSpellChecker(false);
43   } catch (err) {
44     // getInlineSpellChecker throws if spell checking is not enabled instead of
45     // just returning null, which seems kind of lame.  (Spell checking is not
46     // enabled on Android.)  The point here is only to determine whether spell
47     // check is pending, and if getInlineSpellChecker throws, then it's not
48     // pending.
49   }
50   let waitingForEnded = isc && isc.spellCheckPending;
51   let count = 0;
53   function observe(subj, topic) {
54     if (subj != editor) {
55       return;
56     }
57     count = 0;
58     let expectedTopic = waitingForEnded
59       ? SPELL_CHECK_ENDED_TOPIC
60       : SPELL_CHECK_STARTED_TOPIC;
61     if (topic != expectedTopic) {
62       console.error("Expected " + expectedTopic + " but got " + topic + "!");
63     }
64     waitingForEnded = !waitingForEnded;
65   }
67   // eslint-disable-next-line mozilla/use-services
68   let os = Cc["@mozilla.org/observer-service;1"].getService(
69     Ci.nsIObserverService
70   );
71   os.addObserver(observe, SPELL_CHECK_STARTED_TOPIC);
72   os.addObserver(observe, SPELL_CHECK_ENDED_TOPIC);
74   let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
75   timer.init(
76     function tick() {
77       // Wait an arbitrarily large number -- 100 -- turns of the event loop before
78       // declaring that no spell checks will start.
79       if (waitingForEnded || ++count < 100) {
80         return;
81       }
82       timer.cancel();
83       os.removeObserver(observe, SPELL_CHECK_STARTED_TOPIC);
84       os.removeObserver(observe, SPELL_CHECK_ENDED_TOPIC);
85       callback();
86     },
87     0,
88     Ci.nsITimer.TYPE_REPEATING_SLACK
89   );
92 /**
93  * Waits until spell checking has stopped on the given element.
94  *
95  * @param editableElement  The element being spell checked.
96  * @param callback         Called when spell check has completed or enough turns
97  *                         of the event loop have passed to determine it has not
98  *                         started.
99  */
100 export function onSpellCheck(editableElement, callback) {
101   const { TestUtils } = ChromeUtils.importESModule(
102     "resource://testing-common/TestUtils.sys.mjs"
103   );
105   let editor = editableElement.editor;
106   TestUtils.topicObserved(SPELL_CHECK_ENDED_TOPIC, s => s == editor).then(
107     callback
108   );
111 export async function getDictionaryContentPref() {
112   let dictionaries = await new Promise(resolve => {
113     let value = "";
114     CP.getByDomainAndName("mochi.test", "spellcheck.lang", null, {
115       handleResult(pref) {
116         value = pref.value;
117       },
118       handleCompletion() {
119         resolve(value);
120       },
121     });
122   });
124   return dictionaries;