1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef mozSpellChecker_h__
7 #define mozSpellChecker_h__
8 
9 #include "mozilla/MozPromise.h"
10 #include "nsCOMPtr.h"
11 #include "nsCOMArray.h"
12 #include "nsString.h"
13 #include "mozIPersonalDictionary.h"
14 #include "mozISpellCheckingEngine.h"
15 #include "nsClassHashtable.h"
16 #include "nsTArray.h"
17 #include "nsCycleCollectionParticipant.h"
18 
19 class mozEnglishWordUtils;
20 
21 namespace mozilla {
22 class RemoteSpellcheckEngineChild;
23 class TextServicesDocument;
24 typedef MozPromise<CopyableTArray<bool>, nsresult, false> CheckWordPromise;
25 typedef MozPromise<CopyableTArray<nsString>, nsresult, false>
26     SuggestionsPromise;
27 }  // namespace mozilla
28 
29 class mozSpellChecker final {
30  public:
NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(mozSpellChecker)31   NS_INLINE_DECL_CYCLE_COLLECTING_NATIVE_REFCOUNTING(mozSpellChecker)
32   NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(mozSpellChecker)
33 
34   static already_AddRefed<mozSpellChecker> Create() {
35     RefPtr<mozSpellChecker> spellChecker = new mozSpellChecker();
36     nsresult rv = spellChecker->Init();
37     NS_ENSURE_SUCCESS(rv, nullptr);
38     return spellChecker.forget();
39   }
40 
41   /**
42    * Tells the spellchecker what document to check.
43    * @param aDoc is the document to check.
44    * @param aFromStartOfDoc If true, start check from beginning of document,
45    * if false, start check from current cursor position.
46    */
47   nsresult SetDocument(mozilla::TextServicesDocument* aTextServicesDocument,
48                        bool aFromStartofDoc);
49 
50   /**
51    * Selects (hilites) the next misspelled word in the document.
52    * @param aWord will contain the misspelled word.
53    * @param aSuggestions is an array of nsStrings, that represent the
54    * suggested replacements for the misspelled word.
55    */
56   MOZ_CAN_RUN_SCRIPT
57   nsresult NextMisspelledWord(nsAString& aWord,
58                               nsTArray<nsString>& aSuggestions);
59 
60   /**
61    * Checks if a word is misspelled. No document is required to use this method.
62    * @param aWord is the word to check.
63    * @param aIsMisspelled will be set to true if the word is misspelled.
64    * @param aSuggestions is an array of nsStrings which represent the
65    * suggested replacements for the misspelled word. The array will be empty
66    * in chrome process if there aren't any suggestions. If suggestions is
67    * unnecessary, use CheckWords of async version.
68    */
69   nsresult CheckWord(const nsAString& aWord, bool* aIsMisspelled,
70                      nsTArray<nsString>* aSuggestions);
71 
72   /**
73    * This is a flavor of CheckWord, is async version of CheckWord.
74    * @Param aWords is array of words to check
75    */
76   RefPtr<mozilla::CheckWordPromise> CheckWords(
77       const nsTArray<nsString>& aWords);
78 
79   /*
80    * Checks if a word is misspelled, then get suggestion words if existed.
81    */
82   RefPtr<mozilla::SuggestionsPromise> Suggest(const nsAString& aWord,
83                                               uint32_t aMaxCount);
84 
85   /**
86    * Replaces the old word with the specified new word.
87    * @param aOldWord is the word to be replaced.
88    * @param aNewWord is the word that is to replace old word.
89    * @param aAllOccurrences will replace all occurrences of old
90    * word, in the document, with new word when it is true. If
91    * false, it will replace the 1st occurrence only!
92    */
93   MOZ_CAN_RUN_SCRIPT
94   nsresult Replace(const nsAString& aOldWord, const nsAString& aNewWord,
95                    bool aAllOccurrences);
96 
97   /**
98    * Ignores all occurrences of the specified word in the document.
99    * @param aWord is the word to ignore.
100    */
101   nsresult IgnoreAll(const nsAString& aWord);
102 
103   /**
104    * Add a word to the user's personal dictionary.
105    * @param aWord is the word to add.
106    */
107   nsresult AddWordToPersonalDictionary(const nsAString& aWord);
108 
109   /**
110    * Remove a word from the user's personal dictionary.
111    * @param aWord is the word to remove.
112    */
113   nsresult RemoveWordFromPersonalDictionary(const nsAString& aWord);
114 
115   /**
116    * Returns the list of words in the user's personal dictionary.
117    * @param aWordList is an array of nsStrings that represent the
118    * list of words in the user's personal dictionary.
119    */
120   nsresult GetPersonalDictionary(nsTArray<nsString>* aWordList);
121 
122   /**
123    * Returns the list of strings representing the dictionaries
124    * the spellchecker supports. It was suggested that the strings
125    * returned be in the RFC 1766 format. This format looks something
126    * like <ISO 639 language code>-<ISO 3166 country code>.
127    * For example: en-US
128    * @param aDictionaryList is an array of nsStrings that represent the
129    * dictionaries supported by the spellchecker.
130    */
131   nsresult GetDictionaryList(nsTArray<nsCString>* aDictionaryList);
132 
133   /**
134    * Returns a string representing the current dictionary.
135    * @param aDictionary will contain the name of the dictionary.
136    * This name is the same string that is in the list returned
137    * by GetDictionaryList().
138    */
139   nsresult GetCurrentDictionary(nsACString& aDictionary);
140 
141   /**
142    * Tells the spellchecker to use a specific dictionary.
143    * @param aDictionary a string that is in the list returned
144    * by GetDictionaryList() or an empty string. If aDictionary is
145    * empty string, spellchecker will be disabled.
146    */
147   nsresult SetCurrentDictionary(const nsACString& aDictionary);
148 
149   /**
150    * Tells the spellchecker to use a specific dictionary from list.
151    * @param aList  a preferred dictionary list
152    */
153   RefPtr<mozilla::GenericPromise> SetCurrentDictionaryFromList(
154       const nsTArray<nsCString>& aList);
155 
DeleteRemoteEngine()156   void DeleteRemoteEngine() { mEngine = nullptr; }
157 
158   mozilla::TextServicesDocument* GetTextServicesDocument();
159 
160  protected:
161   mozSpellChecker();
162   virtual ~mozSpellChecker();
163 
164   nsresult Init();
165 
166   RefPtr<mozEnglishWordUtils> mConverter;
167   RefPtr<mozilla::TextServicesDocument> mTextServicesDocument;
168   nsCOMPtr<mozIPersonalDictionary> mPersonalDictionary;
169 
170   nsCOMPtr<mozISpellCheckingEngine> mSpellCheckingEngine;
171   bool mFromStart;
172 
173   nsCString mCurrentDictionary;
174 
175   MOZ_CAN_RUN_SCRIPT
176   nsresult SetupDoc(int32_t* outBlockOffset);
177 
178   nsresult GetCurrentBlockIndex(
179       mozilla::TextServicesDocument* aTextServicesDocument,
180       int32_t* aOutBlockIndex);
181 
182   nsresult GetEngineList(nsCOMArray<mozISpellCheckingEngine>* aDictionaryList);
183 
184   mozilla::RemoteSpellcheckEngineChild* mEngine;
185 
186   friend class mozilla::RemoteSpellcheckEngineChild;
187 };
188 #endif  // mozSpellChecker_h__
189