Bug fix: Append a language to the list after blocking it for Translate on Chrome OS

Chrome OS and the other platforms are different in terms of the preference for the language list of chrome://settings/languages, so I factored the functions to manipulate the list and have it called when blocking the language for Translate.

NOTE: Removed DCHECK(...) in translate_infobar_delegate.cc to check if the language is listed in the blocked language list here because the language might already be listed. For example:
1. After the user add the language, he/she removes the language chrome://settings/languages. In this case, Translate infobar will appear.
2. While the Translate infobar is shown, the user can change if Translate should be offered in the language. In this case, the user can push Never Translate (language)" button while the language is already blocked.

BUG=285651

Review URL: https://chromiumcodereview.appspot.com/23923007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@223542 0039d316-1c4b-4281-b951-d872f2087c98
parent 1ab9d0e8
......@@ -407,45 +407,10 @@ cr.define('options', function() {
* Saves the preference.
*/
savePreference_: function() {
// Encode the language codes into a CSV string.
if (cr.isChromeOS)
Preferences.setStringPref(this.preferredLanguagesPref,
this.dataModel.slice().join(','), true);
// Save the same language list as accept languages preference as
// well, but we need to expand the language list, to make it more
// acceptable. For instance, some web sites don't understand 'en-US'
// but 'en'. See crosbug.com/9884.
var acceptLanguages = this.expandLanguageCodes(this.dataModel.slice());
Preferences.setStringPref(this.acceptLanguagesPref,
acceptLanguages.join(','), true);
chrome.send('updateLanguageList', [this.dataModel.slice()]);
cr.dispatchSimpleEvent(this, 'save');
},
/**
* Expands language codes to make these more suitable for Accept-Language.
* Example: ['en-US', 'ja', 'en-CA'] => ['en-US', 'en', 'ja', 'en-CA'].
* 'en' won't appear twice as this function eliminates duplicates.
* @param {Array} languageCodes List of language codes.
* @private
*/
expandLanguageCodes: function(languageCodes) {
var expandedLanguageCodes = [];
var seen = {}; // Used to eliminiate duplicates.
for (var i = 0; i < languageCodes.length; i++) {
var languageCode = languageCodes[i];
if (!(languageCode in seen)) {
expandedLanguageCodes.push(languageCode);
seen[languageCode] = true;
}
var parts = languageCode.split('-');
if (!(parts[0] in seen)) {
expandedLanguageCodes.push(parts[0]);
seen[parts[0]] = true;
}
}
return expandedLanguageCodes;
},
/**
* Filters bad language codes in case bad language codes are
* stored in the preference. Removes duplicates as well.
......
......@@ -211,7 +211,6 @@ void TranslateInfoBarDelegate::AlwaysTranslatePageLanguage() {
void TranslateInfoBarDelegate::NeverTranslatePageLanguage() {
std::string original_lang = original_language_code();
DCHECK(!prefs_.IsBlockedLanguage(original_lang));
prefs_.BlockLanguage(original_lang);
RemoveSelf();
}
......
......@@ -4,6 +4,8 @@
#include "chrome/browser/translate/translate_prefs.h"
#include <set>
#include "base/prefs/pref_service.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
......@@ -33,6 +35,7 @@ namespace {
void GetBlacklistedLanguages(const PrefService* prefs,
std::vector<std::string>* languages) {
DCHECK(languages);
DCHECK(languages->empty());
const char* key = TranslatePrefs::kPrefTranslateLanguageBlacklist;
......@@ -64,34 +67,39 @@ std::string ConvertLangCodeForTranslation(const std::string &lang) {
return main_part;
}
} // namespace
namespace {
// Expands language codes to make these more suitable for Accept-Language.
// Example: ['en-US', 'ja', 'en-CA'] => ['en-US', 'en', 'ja', 'en-CA'].
// 'en' won't appear twice as this function eliminates duplicates.
void ExpandLanguageCodes(const std::vector<std::string>& languages,
std::vector<std::string>* expanded_languages) {
DCHECK(expanded_languages);
DCHECK(expanded_languages->empty());
void AppendLanguageToAcceptLanguages(PrefService* prefs,
const std::string& language) {
if (!TranslateAcceptLanguages::CanBeAcceptLanguage(language))
return;
// used to eliminate duplicates.
std::set<std::string> seen;
std::string accept_language = language;
TranslateUtil::ToChromeLanguageSynonym(&accept_language);
for (std::vector<std::string>::const_iterator it = languages.begin();
it != languages.end(); ++it) {
const std::string& language = *it;
if (seen.find(language) == seen.end()) {
expanded_languages->push_back(language);
seen.insert(language);
}
std::string accept_languages_str = prefs->GetString(prefs::kAcceptLanguages);
std::vector<std::string> accept_languages;
base::SplitString(accept_languages_str, ',', &accept_languages);
if (std::find(accept_languages.begin(),
accept_languages.end(),
accept_language) == accept_languages.end()) {
accept_languages.push_back(accept_language);
std::vector<std::string> tokens;
base::SplitString(language, '-', &tokens);
if (tokens.size() == 0)
continue;
const std::string& main_part = tokens[0];
if (seen.find(main_part) == seen.end()) {
expanded_languages->push_back(main_part);
seen.insert(main_part);
}
}
accept_languages_str = JoinString(accept_languages, ',');
prefs->SetString(prefs::kAcceptLanguages, accept_languages_str);
}
} // namespace
// TranslatePrefs: public: -----------------------------------------------------
TranslatePrefs::TranslatePrefs(PrefService* user_prefs)
: prefs_(user_prefs) {
}
......@@ -105,7 +113,19 @@ bool TranslatePrefs::IsBlockedLanguage(
void TranslatePrefs::BlockLanguage(
const std::string& original_language) {
BlacklistValue(kPrefTranslateBlockedLanguages, original_language);
AppendLanguageToAcceptLanguages(prefs_, original_language);
// Add the language to the language list at chrome://settings/languages.
std::string language = original_language;
TranslateUtil::ToChromeLanguageSynonym(&language);
std::vector<std::string> languages;
GetLanguageList(&languages);
if (std::find(languages.begin(), languages.end(), language) ==
languages.end()) {
languages.push_back(language);
UpdateLanguageList(languages);
}
}
void TranslatePrefs::UnblockLanguage(
......@@ -238,7 +258,35 @@ void TranslatePrefs::ResetTranslationAcceptedCount(
update.Get()->SetInteger(language, 0);
}
// TranslatePrefs: public, static: ---------------------------------------------
void TranslatePrefs::GetLanguageList(std::vector<std::string>* languages) {
DCHECK(languages);
DCHECK(languages->empty());
#if defined(OS_CHROMEOS)
const char* key = prefs::kLanguagePreferredLanguages;
#else
const char* key = prefs::kAcceptLanguages;
#endif
std::string languages_str = prefs_->GetString(key);
base::SplitString(languages_str, ',', languages);
}
void TranslatePrefs::UpdateLanguageList(
const std::vector<std::string>& languages) {
#if defined(OS_CHROMEOS)
std::string languages_str = JoinString(languages, ',');
prefs_->SetString(prefs::kLanguagePreferredLanguages, languages_str);
#endif
// Save the same language list as accept languages preference as well, but we
// need to expand the language list, to make it more acceptable. For instance,
// some web sites don't understand 'en-US' but 'en'. See crosbug.com/9884.
std::vector<std::string> accept_languages;
ExpandLanguageCodes(languages, &accept_languages);
std::string accept_languages_str = JoinString(accept_languages, ',');
prefs_->SetString(prefs::kAcceptLanguages, accept_languages_str);
}
// static
bool TranslatePrefs::CanTranslateLanguage(Profile* profile,
......@@ -386,13 +434,12 @@ void TranslatePrefs::MigrateUserPrefs(PrefService* user_prefs) {
}
}
// TranslatePrefs: private: ----------------------------------------------------
// static
void TranslatePrefs::CreateBlockedLanguages(
std::vector<std::string>* blocked_languages,
const std::vector<std::string>& blacklisted_languages,
const std::vector<std::string>& accept_languages) {
DCHECK(blocked_languages);
DCHECK(blocked_languages->empty());
std::set<std::string> result;
......
......@@ -79,6 +79,12 @@ class TranslatePrefs {
void IncrementTranslationAcceptedCount(const std::string& language);
void ResetTranslationAcceptedCount(const std::string& language);
// Sets the language list of chrome://settings/languages.
void GetLanguageList(std::vector<std::string>* languages);
// Updates the language list of chrome://settings/languages.
void UpdateLanguageList(const std::vector<std::string>& languages);
static bool CanTranslateLanguage(
Profile* profile, const std::string& language);
static bool ShouldAutoTranslate(PrefService* user_prefs,
......
......@@ -22,6 +22,7 @@
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/browser/translate/translate_manager.h"
#include "chrome/browser/translate/translate_prefs.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
......@@ -163,6 +164,10 @@ void LanguageOptionsHandlerCommon::RegisterMessages() {
base::Bind(
&LanguageOptionsHandlerCommon::RetrySpellcheckDictionaryDownload,
base::Unretained(this)));
web_ui()->RegisterMessageCallback("updateLanguageList",
base::Bind(
&LanguageOptionsHandlerCommon::UpdateLanguageListCallback,
base::Unretained(this)));
}
void LanguageOptionsHandlerCommon::OnHunspellDictionaryInitialized() {
......@@ -240,6 +245,27 @@ void LanguageOptionsHandlerCommon::SpellCheckLanguageChangeCallback(
RefreshHunspellDictionary();
}
void LanguageOptionsHandlerCommon::UpdateLanguageListCallback(
const ListValue* args) {
CHECK_EQ(args->GetSize(), 1u);
const ListValue* language_list;
args->GetList(0, &language_list);
DCHECK(language_list);
std::vector<std::string> languages;
for (ListValue::const_iterator it = language_list->begin();
it != language_list->end(); ++it) {
std::string lang;
(*it)->GetAsString(&lang);
languages.push_back(lang);
}
Profile* profile = Profile::FromWebUI(web_ui());
PrefService* prefs = profile->GetPrefs();
TranslatePrefs translate_prefs(prefs);
translate_prefs.UpdateLanguageList(languages);
}
void LanguageOptionsHandlerCommon::RetrySpellcheckDictionaryDownload(
const ListValue* args) {
GetHunspellDictionary()->RetryDownloadDictionary(
......
......@@ -79,6 +79,9 @@ class LanguageOptionsHandlerCommon
// has failed to download.
void RetrySpellcheckDictionaryDownload(const base::ListValue* args);
// Called when the user saves the language list preferences.
void UpdateLanguageListCallback(const base::ListValue* args);
// Updates the hunspell dictionary that is used for spellchecking.
void RefreshHunspellDictionary();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment