summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrouslan <rouslan@chromium.org>2016-02-16 13:52:24 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-16 21:53:49 +0000
commiteb3f08b2ec5edb33108b07ca784508969ff95384 (patch)
tree0a1ee4f6e019c0a3972da6c9b748fce62e1b8aca
parent6044a028d31c8459afb0a7ef5df5ab99f51a0db4 (diff)
downloadchromium_src-eb3f08b2ec5edb33108b07ca784508969ff95384.zip
chromium_src-eb3f08b2ec5edb33108b07ca784508969ff95384.tar.gz
chromium_src-eb3f08b2ec5edb33108b07ca784508969ff95384.tar.bz2
[spellcheck] Preserve the order of spellcheck languages.
GetDictionaries() is used for displaying spellcheck languages in the context menu. The ordering of languages should be always preserved for UI consistency. BUG=584517 Review URL: https://codereview.chromium.org/1679073002 Cr-Commit-Position: refs/heads/master@{#375670}
-rw-r--r--chrome/browser/spellchecker/spellcheck_service.cc52
-rw-r--r--chrome/browser/spellchecker/spellcheck_service.h24
-rw-r--r--chrome/browser/spellchecker/spellcheck_service_unittest.cc126
-rw-r--r--chrome/common/spellcheck_common.h8
4 files changed, 127 insertions, 83 deletions
diff --git a/chrome/browser/spellchecker/spellcheck_service.cc b/chrome/browser/spellchecker/spellcheck_service.cc
index b766b24..7360f06 100644
--- a/chrome/browser/spellchecker/spellcheck_service.cc
+++ b/chrome/browser/spellchecker/spellcheck_service.cc
@@ -4,7 +4,7 @@
#include "chrome/browser/spellchecker/spellcheck_service.h"
-#include <algorithm>
+#include <set>
#include "base/logging.h"
#include "base/strings/string_split.h"
@@ -129,34 +129,32 @@ base::WeakPtr<SpellcheckService> SpellcheckService::GetWeakPtr() {
#if !defined(OS_MACOSX)
// static
-size_t SpellcheckService::GetSpellCheckLanguages(
- base::SupportsUserData* context,
- std::vector<std::string>* languages) {
- PrefService* prefs = user_prefs::UserPrefs::Get(context);
- StringPrefMember accept_languages_pref;
- accept_languages_pref.Init(prefs::kAcceptLanguages, prefs);
-
- std::vector<std::string> accept_languages = base::SplitString(
- accept_languages_pref.GetValue(), ",",
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
-
- StringListPrefMember dictionaries_pref;
- dictionaries_pref.Init(prefs::kSpellCheckDictionaries, prefs);
- *languages = dictionaries_pref.GetValue();
- size_t enabled_spellcheck_languages = languages->size();
-
- for (std::vector<std::string>::const_iterator i = accept_languages.begin();
- i != accept_languages.end(); ++i) {
- std::string language =
- chrome::spellcheck_common::GetCorrespondingSpellCheckLanguage(*i);
- if (!language.empty() &&
- std::find(languages->begin(), languages->end(), language) ==
- languages->end()) {
- languages->push_back(language);
- }
+void SpellcheckService::GetDictionaries(base::SupportsUserData* browser_context,
+ std::vector<Dictionary>* dictionaries) {
+ PrefService* prefs = user_prefs::UserPrefs::Get(browser_context);
+ std::set<std::string> spellcheck_dictionaries;
+ for (const auto& value : *prefs->GetList(prefs::kSpellCheckDictionaries)) {
+ std::string dictionary;
+ if (value->GetAsString(&dictionary))
+ spellcheck_dictionaries.insert(dictionary);
}
- return enabled_spellcheck_languages;
+ dictionaries->clear();
+ std::vector<std::string> accept_languages =
+ base::SplitString(prefs->GetString(prefs::kAcceptLanguages), ",",
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ for (const auto& accept_language : accept_languages) {
+ Dictionary dictionary;
+ dictionary.language =
+ chrome::spellcheck_common::GetCorrespondingSpellCheckLanguage(
+ accept_language);
+ if (dictionary.language.empty())
+ continue;
+
+ dictionary.used_for_spellcheck =
+ spellcheck_dictionaries.count(dictionary.language) > 0;
+ dictionaries->push_back(dictionary);
+ }
}
#endif // !OS_MACOSX
diff --git a/chrome/browser/spellchecker/spellcheck_service.h b/chrome/browser/spellchecker/spellcheck_service.h
index b2a03b4..f2ddd19 100644
--- a/chrome/browser/spellchecker/spellcheck_service.h
+++ b/chrome/browser/spellchecker/spellcheck_service.h
@@ -63,19 +63,29 @@ class SpellcheckService : public KeyedService,
DICT_UNKNOWN,
};
+ // A dictionary that can be used for spellcheck.
+ struct Dictionary {
+ // The shortest unambiguous identifier for a language from
+ // |g_supported_spellchecker_languages|. For example, "bg" for Bulgarian,
+ // because Chrome has only one Bulgarian language. However, "en-US" for
+ // English (United States), because Chrome has several versions of English.
+ std::string language;
+
+ // Whether |language| is currently used for spellcheck.
+ bool used_for_spellcheck;
+ };
+
explicit SpellcheckService(content::BrowserContext* context);
~SpellcheckService() override;
base::WeakPtr<SpellcheckService> GetWeakPtr();
#if !defined(OS_MACOSX)
- // Computes |languages| to display in the context menu over a text area for
- // changing spellcheck languages. Returns the number of languages that are
- // enabled, which are always at the beginning of |languages|.
- // TODO(port): this should take a vector of base::string16, but the
- // implementation has some dependencies in l10n util that need porting first.
- static size_t GetSpellCheckLanguages(base::SupportsUserData* context,
- std::vector<std::string>* languages);
+ // Returns all currently configured |dictionaries| to display in the context
+ // menu over a text area. The context menu is used for selecting the
+ // dictionaries used for spellcheck.
+ static void GetDictionaries(base::SupportsUserData* browser_context,
+ std::vector<Dictionary>* dictionaries);
#endif // !OS_MACOSX
// Signals the event attached by AttachTestEvent() to report the specified
diff --git a/chrome/browser/spellchecker/spellcheck_service_unittest.cc b/chrome/browser/spellchecker/spellcheck_service_unittest.cc
index 1d46e0c..bdd0a76 100644
--- a/chrome/browser/spellchecker/spellcheck_service_unittest.cc
+++ b/chrome/browser/spellchecker/spellcheck_service_unittest.cc
@@ -4,12 +4,13 @@
#include "chrome/browser/spellchecker/spellcheck_service.h"
-#include <stddef.h>
+#include <ostream>
#include "base/command_line.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/strings/string_split.h"
+#include "base/strings/string_util.h"
#include "base/supports_user_data.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
@@ -19,31 +20,68 @@
#include "content/public/test/test_browser_thread.h"
#include "testing/gtest/include/gtest/gtest.h"
-struct SpellcheckLanguageTestCase {
- SpellcheckLanguageTestCase(const std::string& accept_languages,
- const std::string& unsplit_spellcheck_dictionaries,
- size_t num_expected_enabled_spellcheck_languages,
- const std::string& unsplit_expected_languages)
+struct TestCase {
+ TestCase(const std::string& accept_languages,
+ const std::string& unsplit_spellcheck_dictionaries,
+ const std::string& unsplit_expected_languages,
+ const std::string& unsplit_expected_languages_used_for_spellcheck)
: accept_languages(accept_languages),
- num_expected_enabled_spellcheck_languages(
- num_expected_enabled_spellcheck_languages) {
- spellcheck_dictionaries = base::SplitString(
- unsplit_spellcheck_dictionaries, ",",
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
- expected_spellcheck_languages = base::SplitString(
- unsplit_expected_languages, ",",
- base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+ spellcheck_dictionaries(
+ base::SplitString(unsplit_spellcheck_dictionaries,
+ ",",
+ base::TRIM_WHITESPACE,
+ base::SPLIT_WANT_ALL)) {
+ std::vector<std::string> languages =
+ base::SplitString(unsplit_expected_languages, ",",
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ std::vector<std::string> used_for_spellcheck =
+ base::SplitString(unsplit_expected_languages_used_for_spellcheck, ",",
+ base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
+
+ SpellcheckService::Dictionary dictionary;
+ for (const auto& language : languages) {
+ dictionary.language = language;
+ dictionary.used_for_spellcheck =
+ std::find(used_for_spellcheck.begin(), used_for_spellcheck.end(),
+ language) != used_for_spellcheck.end();
+ expected_dictionaries.push_back(dictionary);
+ }
}
- ~SpellcheckLanguageTestCase() {}
+
+ ~TestCase() {}
std::string accept_languages;
std::vector<std::string> spellcheck_dictionaries;
- size_t num_expected_enabled_spellcheck_languages;
- std::vector<std::string> expected_spellcheck_languages;
+ std::vector<SpellcheckService::Dictionary> expected_dictionaries;
};
-class SpellcheckServiceUnitTest
- : public testing::TestWithParam<SpellcheckLanguageTestCase> {
+bool operator==(const SpellcheckService::Dictionary& lhs,
+ const SpellcheckService::Dictionary& rhs) {
+ return lhs.language == rhs.language &&
+ lhs.used_for_spellcheck == rhs.used_for_spellcheck;
+}
+
+std::ostream& operator<<(std::ostream& out,
+ const SpellcheckService::Dictionary& dictionary) {
+ out << "{\"" << dictionary.language << "\", used_for_spellcheck="
+ << (dictionary.used_for_spellcheck ? "true " : "false") << "}";
+ return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const TestCase& test_case) {
+ out << "prefs::kAcceptLanguages=[" << test_case.accept_languages
+ << "], prefs::kSpellCheckDictionaries=["
+ << base::JoinString(test_case.spellcheck_dictionaries, ",")
+ << "], expected=[";
+ for (const auto& dictionary : test_case.expected_dictionaries) {
+ out << dictionary << ",";
+ }
+ out << "]";
+ return out;
+}
+
+class SpellcheckServiceUnitTest : public testing::TestWithParam<TestCase> {
public:
SpellcheckServiceUnitTest()
: ui_thread_(content::BrowserThread::UI, &message_loop_) {
@@ -61,7 +99,8 @@ class SpellcheckServiceUnitTest
TestingPrefServiceSimple* prefs() { return &prefs_; }
private:
- struct : public base::SupportsUserData {} context_;
+ struct : public base::SupportsUserData {
+ } context_;
TestingPrefServiceSimple prefs_;
base::MessageLoop message_loop_;
content::TestBrowserThread ui_thread_;
@@ -70,38 +109,27 @@ class SpellcheckServiceUnitTest
};
INSTANTIATE_TEST_CASE_P(
- SpellcheckLanguageTestCases,
+ TestCases,
SpellcheckServiceUnitTest,
testing::Values(
- SpellcheckLanguageTestCase("en,en-US", "en-US", 1UL, "en-US"),
- SpellcheckLanguageTestCase("en-US,en", "en-US", 1UL, "en-US"),
- SpellcheckLanguageTestCase("en,en-US,en-AU",
- "en-US",
- 1UL,
- "en-US,en-AU"),
- SpellcheckLanguageTestCase("en,en-US,fr", "en-US", 1UL, "en-US,fr"),
- SpellcheckLanguageTestCase("en,en-JP,fr,aa", "fr", 1UL, "fr"),
- SpellcheckLanguageTestCase("en,en-US", "en-US", 1UL, "en-US"),
- SpellcheckLanguageTestCase("en-US,en", "en-US", 1UL, "en-US"),
- SpellcheckLanguageTestCase("en,fr,en-US,en-AU",
- "en-US,fr",
- 2UL,
- "en-US,fr,en-AU"),
- SpellcheckLanguageTestCase("en,en-JP,fr,zz,en-US",
- "fr",
- 1UL,
- "fr,en-US")));
-
-TEST_P(SpellcheckServiceUnitTest, GetSpellcheckLanguages) {
+ TestCase("en,en-JP,fr,aa", "fr", "fr", "fr"),
+ TestCase("en,en-JP,fr,zz,en-US", "fr", "fr,en-US", "fr"),
+ TestCase("en,en-US,en-AU", "en-AU", "en-US,en-AU", "en-AU"),
+ TestCase("en,en-US,en-AU", "en-US", "en-US,en-AU", "en-US"),
+ TestCase("en,en-US", "en-US", "en-US", "en-US"),
+ TestCase("en,en-US,fr", "en-US", "en-US,fr", "en-US"),
+ TestCase("en,fr,en-US,en-AU", "en-US,fr", "fr,en-US,en-AU", "fr,en-US"),
+ TestCase("en-US,en", "en-US", "en-US", "en-US"),
+ TestCase("hu-HU,hr-HR", "hr", "hu,hr", "hr")));
+
+TEST_P(SpellcheckServiceUnitTest, GetDictionaries) {
prefs()->SetString(prefs::kAcceptLanguages, GetParam().accept_languages);
- base::ListValue dictionaries;
- dictionaries.AppendStrings(GetParam().spellcheck_dictionaries);
- prefs()->Set(prefs::kSpellCheckDictionaries, dictionaries);
+ base::ListValue spellcheck_dictionaries;
+ spellcheck_dictionaries.AppendStrings(GetParam().spellcheck_dictionaries);
+ prefs()->Set(prefs::kSpellCheckDictionaries, spellcheck_dictionaries);
- std::vector<std::string> spellcheck_languages;
- EXPECT_EQ(GetParam().num_expected_enabled_spellcheck_languages,
- SpellcheckService::GetSpellCheckLanguages(context(),
- &spellcheck_languages));
+ std::vector<SpellcheckService::Dictionary> dictionaries;
+ SpellcheckService::GetDictionaries(context(), &dictionaries);
- EXPECT_EQ(GetParam().expected_spellcheck_languages, spellcheck_languages);
+ EXPECT_EQ(GetParam().expected_dictionaries, dictionaries);
}
diff --git a/chrome/common/spellcheck_common.h b/chrome/common/spellcheck_common.h
index b237b26..a7bc3dd 100644
--- a/chrome/common/spellcheck_common.h
+++ b/chrome/common/spellcheck_common.h
@@ -42,6 +42,14 @@ static const size_t MAX_CUSTOM_DICTIONARY_WORD_BYTES = 99;
base::FilePath GetVersionedFileName(const std::string& input_language,
const base::FilePath& dict_dir);
+// Returns the spellcheck language that should be used for |language|. For
+// example, converts "hu-HU" into "hu", because we have only one variant of
+// Hungarian. Converts "en-US" into "en-US", because we have several variants of
+// English dictionaries.
+//
+// Returns an empty string if no spellcheck language found. For example, there's
+// no single dictionary for English, so this function returns an empty string
+// for "en".
std::string GetCorrespondingSpellCheckLanguage(const std::string& language);
// Get SpellChecker supported languages.