Bug 1395443 - DictionaryFetcher::Fetch should initializate nsIContentPrefService2 by idle thread. r?masayuki draft
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Mon, 04 Sep 2017 19:57:45 +0900
changeset 658871 328a994b6c107a122caf60b0d6f8fb5bd10f2f98
parent 658358 8e05298328da75f3056a9f1f9609938870d756a0
child 729783 86f985688c89b0109203afc58dd403fdd54c06ce
push id77910
push userbmo:m_kato@ga2.so-net.ne.jp
push dateTue, 05 Sep 2017 03:09:31 +0000
reviewersmasayuki
bugs1395443
milestone57.0a1
Bug 1395443 - DictionaryFetcher::Fetch should initializate nsIContentPrefService2 by idle thread. r?masayuki When using contenteditable with spellchecker (it is by default), spellchecker will be initialized by mozilla::EditorEventListener::Focus. This method will call nsEditorSpellCheck::UpdateCurrentDictionary, but this method seems to be slow. DictionaryFetcher::Fetch gets nsIContentPrefService2 that is implemented by JavaScript, so we should create nsIContentPrefService2 out of Fetch method. MozReview-Commit-ID: 1fxug0sqD72
editor/composer/nsEditorSpellCheck.cpp
--- a/editor/composer/nsEditorSpellCheck.cpp
+++ b/editor/composer/nsEditorSpellCheck.cpp
@@ -150,40 +150,80 @@ public:
 
 private:
   ~DictionaryFetcher() {}
 
   RefPtr<nsEditorSpellCheck> mSpellCheck;
 };
 NS_IMPL_ISUPPORTS(DictionaryFetcher, nsIContentPrefCallback2)
 
+class ContentPrefInitializerRunnable final : public Runnable
+{
+public:
+  ContentPrefInitializerRunnable(nsIEditor* aEditor,
+                                 nsIContentPrefCallback2* aCallback)
+    : Runnable("ContentPrefInitializerRunnable")
+    , mEditor(aEditor)
+    , mCallback(aCallback)
+  {
+  }
+
+  NS_IMETHOD Run() override
+  {
+    if (mEditor->AsEditorBase()->Destroyed()) {
+      mCallback->HandleError(NS_ERROR_NOT_AVAILABLE);
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsIContentPrefService2> contentPrefService =
+      do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
+    if (NS_WARN_IF(!contentPrefService)) {
+      mCallback->HandleError(NS_ERROR_NOT_AVAILABLE);
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsIURI> docUri;
+    nsresult rv = GetDocumentURI(mEditor, getter_AddRefs(docUri));
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      mCallback->HandleError(rv);
+      return NS_OK;
+    }
+
+    nsAutoCString docUriSpec;
+    rv = docUri->GetSpec(docUriSpec);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      mCallback->HandleError(rv);
+      return NS_OK;
+    }
+
+    nsCOMPtr<nsILoadContext> loadContext = GetLoadContext(mEditor);
+    rv = contentPrefService->GetByDomainAndName(
+                               NS_ConvertUTF8toUTF16(docUriSpec),
+                               CPS_PREF_NAME, loadContext,
+                               mCallback);
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      mCallback->HandleError(rv);
+      return NS_OK;
+    }
+    return NS_OK;
+  }
+
+private:
+  nsCOMPtr<nsIEditor> mEditor;
+  nsCOMPtr<nsIContentPrefCallback2> mCallback;
+};
+
 NS_IMETHODIMP
 DictionaryFetcher::Fetch(nsIEditor* aEditor)
 {
   NS_ENSURE_ARG_POINTER(aEditor);
 
-  nsresult rv;
-
-  nsCOMPtr<nsIURI> docUri;
-  rv = GetDocumentURI(aEditor, getter_AddRefs(docUri));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsAutoCString docUriSpec;
-  rv = docUri->GetSpec(docUriSpec);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCOMPtr<nsIContentPrefService2> contentPrefService =
-    do_GetService(NS_CONTENT_PREF_SERVICE_CONTRACTID);
-  NS_ENSURE_TRUE(contentPrefService, NS_ERROR_NOT_AVAILABLE);
-
-  nsCOMPtr<nsILoadContext> loadContext = GetLoadContext(aEditor);
-  rv = contentPrefService->GetByDomainAndName(NS_ConvertUTF8toUTF16(docUriSpec),
-                                              CPS_PREF_NAME, loadContext,
-                                              this);
-  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIRunnable> runnable =
+     new ContentPrefInitializerRunnable(aEditor, this);
+  NS_IdleDispatchToCurrentThread(runnable.forget(), 1000);
 
   return NS_OK;
 }
 
 /**
  * Stores the current dictionary for aEditor's document URL.
  */
 static nsresult