Bug 1365383 - Spellchecker should consider that callback isn't set. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Thu, 18 May 2017 14:50:25 +0900
changeset 580911 f5c2a5a47bf251bb328d892b459ae72919d978c3
parent 579118 41958333867b0f537271dbd4cb4ba9e8a67a85a8
child 629429 bbf862ec095229933963c63196777fb6c0f16317
push id59711
push userm_kato@ga2.so-net.ne.jp
push dateFri, 19 May 2017 04:44:14 +0000
reviewersmasayuki
bugs1365383
milestone55.0a1
Bug 1365383 - Spellchecker should consider that callback isn't set. r?masayuki InitSpellChecker allows that 3rd callback parameter is null. We should consider that it is null. MozReview-Commit-ID: BMAM6BiYlw5
editor/composer/nsEditorSpellCheck.cpp
editor/composer/test/mochitest.ini
editor/composer/test/test_bug1365383.html
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -763,17 +763,19 @@ nsEditorSpellCheck::DictionaryFetched(Di
   RefPtr<nsEditorSpellCheck> kungFuDeathGrip = this;
 
   BeginUpdateDictionary();
 
   if (aFetcher->mGroup < mDictionaryFetcherGroup) {
     // SetCurrentDictionary was called after the fetch started.  Don't overwrite
     // that dictionary with the fetched one.
     EndUpdateDictionary();
-    aFetcher->mCallback->EditorSpellCheckDone();
+    if (aFetcher->mCallback) {
+      aFetcher->mCallback->EditorSpellCheckDone();
+    }
     return NS_OK;
   }
 
   /*
    * We try to derive the dictionary to use based on the following priorities:
    * 1) Content preference, so the language the user set for the site before.
    *    (Introduced in bug 678842 and corrected in bug 717433.)
    * 2) Language set by the website, or any other dictionary that partly
@@ -812,17 +814,19 @@ nsEditorSpellCheck::DictionaryFetched(Di
 #endif
   }
 
   // We obtain a list of available dictionaries.
   AutoTArray<nsString, 8> dictList;
   nsresult rv = mSpellChecker->GetDictionaryList(&dictList);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     EndUpdateDictionary();
-    aFetcher->mCallback->EditorSpellCheckDone();
+    if (aFetcher->mCallback) {
+      aFetcher->mCallback->EditorSpellCheckDone();
+    }
     return rv;
   }
 
   // Priority 1:
   // If we successfully fetched a dictionary from content prefs, do not go
   // further. Use this exact dictionary.
   // Don't use content preferences for editor with eEditorMailMask flag.
   nsAutoString dictName;
@@ -844,17 +848,19 @@ nsEditorSpellCheck::DictionaryFetched(Di
           printf("***** Assigned from content preferences |%s|\n",
                  NS_ConvertUTF16toUTF8(dictName).get());
 #endif
           // We take an early exit here, so let's not forget to clear the word
           // list.
           self->DeleteSuggestedWordList();
 
           self->EndUpdateDictionary();
-          fetcher->mCallback->EditorSpellCheckDone();
+          if (fetcher->mCallback) {
+            fetcher->mCallback->EditorSpellCheckDone();
+          }
         },
         [self, fetcher]() {
           // May be dictionary was uninstalled ?
           // Clear the content preference and continue.
           ClearCurrentDictionary(self->mEditor);
 
           // Priority 2 or later will handled by the following
           self->SetFallbackDictionary(fetcher);
@@ -873,17 +879,19 @@ nsEditorSpellCheck::SetFallbackDictionar
 
   AutoTArray<nsString, 6> tryDictList;
 
   // We obtain a list of available dictionaries.
   AutoTArray<nsString, 8> dictList;
   nsresult rv = mSpellChecker->GetDictionaryList(&dictList);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     EndUpdateDictionary();
-    aFetcher->mCallback->EditorSpellCheckDone();
+    if (aFetcher->mCallback) {
+      aFetcher->mCallback->EditorSpellCheckDone();
+    }
     return;
   }
 
   // Priority 2:
   // After checking the content preferences, we use the language of the element
   // or document.
   nsAutoString dictName(mPreferredLang);
 #ifdef DEBUG_DICT
@@ -967,17 +975,19 @@ nsEditorSpellCheck::SetFallbackDictionar
   nsAutoString currentDictionary;
   GetCurrentDictionary(currentDictionary);
   if (!currentDictionary.IsEmpty() && tryDictList.IsEmpty()) {
 #ifdef DEBUG_DICT
     printf("***** Retrieved current dict |%s|\n",
            NS_ConvertUTF16toUTF8(currentDictionary).get());
 #endif
     EndUpdateDictionary();
-    aFetcher->mCallback->EditorSpellCheckDone();
+    if (aFetcher->mCallback) {
+      aFetcher->mCallback->EditorSpellCheckDone();
+    }
     return;
   }
 
   // Priority 6:
   // Try to get current dictionary from environment variable LANG.
   // LANG = language[_territory][.charset]
   char* env_lang = getenv("LANG");
   if (env_lang) {
@@ -1018,11 +1028,13 @@ nsEditorSpellCheck::SetFallbackDictionar
     __func__,
     [self, fetcher]() {
       // If an error was thrown while setting the dictionary, just
       // fail silently so that the spellchecker dialog is allowed to come
       // up. The user can manually reset the language to their choice on
       // the dialog if it is wrong.
       self->DeleteSuggestedWordList();
       self->EndUpdateDictionary();
-      fetcher->mCallback->EditorSpellCheckDone();
+      if (fetcher->mCallback) {
+        fetcher->mCallback->EditorSpellCheckDone();
+      }
     });
 }
--- a/editor/composer/test/mochitest.ini
+++ b/editor/composer/test/mochitest.ini
@@ -33,8 +33,10 @@ 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'
+[test_bug1365383.html]
+skip-if = os == 'android'
new file mode 100644
--- /dev/null
+++ b/editor/composer/test/test_bug1365383.html
@@ -0,0 +1,46 @@
+<!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.Cc['@mozilla.org/editor/editorspellchecker;1']
+    .createInstance(SpecialPowers.Ci.nsIEditorSpellCheck);
+
+  // 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>