summaryrefslogtreecommitdiff
path: root/chromium/components/spellcheck/renderer/spellcheck.h
blob: 58debac3fb1dac1f395d3c5a1745286394ea1e03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_H_
#define COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_H_

#include <memory>
#include <set>
#include <string>
#include <vector>

#include "base/files/file.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/strings/string16.h"
#include "components/spellcheck/common/spellcheck.mojom.h"
#include "components/spellcheck/renderer/custom_dictionary_engine.h"
#include "components/spellcheck/spellcheck_buildflags.h"
#include "mojo/public/cpp/bindings/binding_set.h"
#include "services/service_manager/public/cpp/binder_registry.h"

class SpellcheckLanguage;
struct SpellCheckResult;

namespace blink {
class WebTextCheckingCompletion;
struct WebTextCheckingResult;
template <typename T> class WebVector;
class WebString;
}

namespace service_manager {
class LocalInterfaceProvider;
}

class DictionaryUpdateObserver {
 public:
  virtual ~DictionaryUpdateObserver() = default;
  // |words_added| is newly added words to dictionary as correct words.
  // OnDictionaryUpdated should be called even if |words_added| empty.
  virtual void OnDictionaryUpdated(
      const blink::WebVector<blink::WebString>& words_added) = 0;
};

// TODO(morrita): Needs reorg with SpellCheckProvider.
// See http://crbug.com/73699.
// Shared spellchecking logic/data for a RenderProcess. All RenderViews use
// this object to perform spellchecking tasks.
class SpellCheck : public base::SupportsWeakPtr<SpellCheck>,
                   public spellcheck::mojom::SpellChecker {
 public:
  // TODO(groby): I wonder if this can be private, non-mac only.
  class SpellcheckRequest;
  enum ResultFilter {
    DO_NOT_MODIFY = 1,  // Do not modify results.
    USE_NATIVE_CHECKER,  // Use native checker to double-check.
  };

  SpellCheck(service_manager::BinderRegistry* registry,
             service_manager::LocalInterfaceProvider* embedder_provider);
  ~SpellCheck() override;

  void AddSpellcheckLanguage(base::File file, const std::string& language);

  // If there are no dictionary files, then this requests them from the browser
  // and does not block. In this case it returns true.
  // If there are dictionary files, but their Hunspell has not been loaded, then
  // this loads their Hunspell.
  // If each dictionary file's Hunspell is already loaded, this does nothing. In
  // both the latter cases it returns false, meaning that it is OK to continue
  // spellchecking.
  bool InitializeIfNeeded();

  // SpellCheck a word.
  // Returns true if spelled correctly for any language in |languages_|, false
  // otherwise.
  // If any spellcheck languages failed to initialize, always returns true.
  // The |tag| parameter should either be a unique identifier for the document
  // that the word came from (if the current platform requires it), or 0.
  // In addition, finds the suggested words for a given word
  // and puts them into |*optional_suggestions|.
  // If the word is spelled correctly, the vector is empty.
  // If optional_suggestions is NULL, suggested words will not be looked up.
  // Note that doing suggest lookups can be slow.
  bool SpellCheckWord(const base::char16* text_begin,
                      int position_in_text,
                      int text_length,
                      int tag,
                      int* misspelling_start,
                      int* misspelling_len,
                      std::vector<base::string16>* optional_suggestions);

  // SpellCheck a paragraph.
  // Returns true if |text| is correctly spelled, false otherwise.
  // If the spellchecker failed to initialize, always returns true.
  bool SpellCheckParagraph(
      const base::string16& text,
      blink::WebVector<blink::WebTextCheckingResult>* results);

  // Requests to spellcheck the specified text in the background. This function
  // posts a background task and calls SpellCheckParagraph() in the task.
#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
  void RequestTextChecking(const base::string16& text,
                           blink::WebTextCheckingCompletion* completion);
#endif

  // Creates a list of WebTextCheckingResult objects (used by WebKit) from a
  // list of SpellCheckResult objects (used by Chrome). This function also
  // checks misspelled words returned by the Spelling service and changes the
  // underline colors of contextually-misspelled words.
  void CreateTextCheckingResults(
      ResultFilter filter,
      int line_offset,
      const base::string16& line_text,
      const std::vector<SpellCheckResult>& spellcheck_results,
      blink::WebVector<blink::WebTextCheckingResult>* textcheck_results);

  bool IsSpellcheckEnabled();

  // Add observer on dictionary update event.
  void AddDictionaryUpdateObserver(DictionaryUpdateObserver* observer);
  // Remove observer on dictionary update event.
  void RemoveDictionaryUpdateObserver(DictionaryUpdateObserver* observer);

 private:
   friend class SpellCheckTest;
   FRIEND_TEST_ALL_PREFIXES(SpellCheckTest, GetAutoCorrectionWord_EN_US);
   FRIEND_TEST_ALL_PREFIXES(SpellCheckTest,
       RequestSpellCheckMultipleTimesWithoutInitialization);

   // Evenly fill |optional_suggestions| with a maximum of |kMaxSuggestions|
   // suggestions from |suggestions_list|. suggestions_list[i][j] is the j-th
   // suggestion from the i-th language's suggestions. |optional_suggestions|
   // cannot be null.
   static void FillSuggestions(
       const std::vector<std::vector<base::string16>>& suggestions_list,
       std::vector<base::string16>* optional_suggestions);

   // Binds requests for the SpellChecker interface.
   void SpellCheckerRequest(spellcheck::mojom::SpellCheckerRequest request);

   // spellcheck::mojom::SpellChecker:
   void Initialize(
       std::vector<spellcheck::mojom::SpellCheckBDictLanguagePtr> dictionaries,
       const std::vector<std::string>& custom_words,
       bool enable) override;
   void CustomDictionaryChanged(
       const std::vector<std::string>& words_added,
       const std::vector<std::string>& words_removed) override;

   // Performs dictionary update notification.
   void NotifyDictionaryObservers(
       const blink::WebVector<blink::WebString>& words_added);

#if !BUILDFLAG(USE_BROWSER_SPELLCHECKER)
  // Posts delayed spellcheck task and clear it if any.
  // Takes ownership of |request|.
  void PostDelayedSpellCheckTask(SpellcheckRequest* request);

  // Performs spell checking from the request queue.
  void PerformSpellCheck(SpellcheckRequest* request);

  // The parameters of a pending background-spellchecking request. When WebKit
  // sends a background-spellchecking request before initializing hunspell,
  // we save its parameters and start spellchecking after we finish initializing
  // hunspell. (When WebKit sends two or more requests, we cancel the previous
  // requests so we do not have to use vectors.)
  std::unique_ptr<SpellcheckRequest> pending_request_param_;
#endif

  // Bindings for SpellChecker clients.
  mojo::BindingSet<spellcheck::mojom::SpellChecker> bindings_;

  // A vector of objects used to actually check spelling, one for each enabled
  // language.
  std::vector<std::unique_ptr<SpellcheckLanguage>> languages_;

  // Custom dictionary spelling engine.
  CustomDictionaryEngine custom_dictionary_;

  service_manager::LocalInterfaceProvider* embedder_provider_;

  // Remember state for spellchecking.
  bool spellcheck_enabled_;

  // Observers of update dictionary events.
  base::ObserverList<DictionaryUpdateObserver> dictionary_update_observers_;

  base::WeakPtrFactory<SpellCheck> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(SpellCheck);
};

#endif  // COMPONENTS_SPELLCHECK_RENDERER_SPELLCHECK_H_