15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "base/files/file.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/weak_ptr.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/strings/string16.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/renderer/spellchecker/custom_dictionary_engine.h"
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/renderer/spellchecker/spellcheck_language.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/renderer/render_process_observer.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_platform_file.h"
20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebVector.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct SpellCheckResult;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)namespace blink {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebTextCheckingCompletion;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct WebTextCheckingResult;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(morrita): Needs reorg with SpellCheckProvider.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See http://crbug.com/73699.
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Shared spellchecking logic/data for a RenderProcess. All RenderViews use
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// this object to perform spellchecking tasks.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SpellCheck : public content::RenderProcessObserver,
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   public base::SupportsWeakPtr<SpellCheck> {
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(groby): I wonder if this can be private, non-mac only.
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  class SpellcheckRequest;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  enum ResultFilter {
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DO_NOT_MODIFY = 1,  // Do not modify results.
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    USE_NATIVE_CHECKER,  // Use native checker to double-check.
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  };
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SpellCheck();
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SpellCheck();
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO: Try to move that all to SpellcheckLanguage.
47effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  void Init(base::File file,
4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)            const std::set<std::string>& custom_words,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const std::string& language);
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there is no dictionary file, then this requests one from the browser
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // and does not block. In this case it returns true.
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If there is a dictionary file, but Hunspell has not been loaded, then
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // this loads Hunspell.
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If Hunspell is already loaded, this does nothing. In both the latter cases
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // it returns false, meaning that it is OK to continue spellchecking.
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool InitializeIfNeeded();
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SpellCheck a word.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if spelled correctly, false otherwise.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the spellchecker failed to initialize, always returns true.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The |tag| parameter should either be a unique identifier for the document
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that the word came from (if the current platform requires it), or 0.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // In addition, finds the suggested words for a given word
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // and puts them into |*optional_suggestions|.
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the word is spelled correctly, the vector is empty.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If optional_suggestions is NULL, suggested words will not be looked up.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that Doing suggest lookups can be slow.
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  bool SpellCheckWord(const base::char16* in_word,
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int in_word_len,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int tag,
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int* misspelling_start,
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      int* misspelling_len,
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                      std::vector<base::string16>* optional_suggestions);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // SpellCheck a paragraph.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if |text| is correctly spelled, false otherwise.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the spellchecker failed to initialize, always returns true.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SpellCheckParagraph(
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& text,
81f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebVector<blink::WebTextCheckingResult>* results);
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Find a possible correctly spelled word for a misspelled word. Computes an
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // empty string if input misspelled word is too long, there is ambiguity, or
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the correct spelling cannot be determined.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // NOTE: If using the platform spellchecker, this will send a *lot* of sync
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // IPCs. We should probably refactor this if we ever plan to take it out from
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // behind its command line flag.
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 GetAutoCorrectionWord(const base::string16& word, int tag);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Requests to spellcheck the specified text in the background. This function
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // posts a background task and calls SpellCheckParagraph() in the task.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined (OS_MACOSX)
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void RequestTextChecking(const base::string16& text,
95f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                           blink::WebTextCheckingCompletion* completion);
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a list of WebTextCheckingResult objects (used by WebKit) from a
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // list of SpellCheckResult objects (used by Chrome). This function also
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // checks misspelled words returned by the Spelling service and changes the
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // underline colors of contextually-misspelled words.
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void CreateTextCheckingResults(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      ResultFilter filter,
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int line_offset,
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const base::string16& line_text,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<SpellCheckResult>& spellcheck_results,
107f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      blink::WebVector<blink::WebTextCheckingResult>* textcheck_results);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool is_spellcheck_enabled() { return spellcheck_enabled_; }
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private:
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   friend class SpellCheckTest;
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   FRIEND_TEST_ALL_PREFIXES(SpellCheckTest, GetAutoCorrectionWord_EN_US);
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)   FRIEND_TEST_ALL_PREFIXES(SpellCheckTest,
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       RequestSpellCheckMultipleTimesWithoutInitialization);
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // RenderProcessObserver implementation:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool OnControlMessageReceived(const IPC::Message& message) OVERRIDE;
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Message handlers.
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnInit(IPC::PlatformFileForTransit bdict_file,
12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)              const std::set<std::string>& custom_words,
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const std::string& language,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              bool auto_spell_correct);
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnCustomDictionaryChanged(
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<std::string>& words_added,
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::vector<std::string>& words_removed);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void OnEnableAutoSpellCorrect(bool enable);
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void OnEnableSpellCheck(bool enable);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void OnRequestDocumentMarkers();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined (OS_MACOSX)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Posts delayed spellcheck task and clear it if any.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Takes ownership of |request|.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PostDelayedSpellCheckTask(SpellcheckRequest* request);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Performs spell checking from the request queue.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PerformSpellCheck(SpellcheckRequest* request);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The parameters of a pending background-spellchecking request. When WebKit
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // sends a background-spellchecking request before initializing hunspell,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we save its parameters and start spellchecking after we finish initializing
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // hunspell. (When WebKit sends two or more requests, we cancel the previous
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // requests so we do not have to use vectors.)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<SpellcheckRequest> pending_request_param_;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpellcheckLanguage spellcheck_;  // Language-specific spellchecking code.
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Custom dictionary spelling engine.
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CustomDictionaryEngine custom_dictionary_;
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remember state for auto spell correct.
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool auto_spell_correct_turned_on_;
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Remember state for spellchecking.
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool spellcheck_enabled_;
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SpellCheck);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_RENDERER_SPELLCHECKER_SPELLCHECK_H_
163