summaryrefslogtreecommitdiffstats
path: root/chrome/browser/translate/translate_manager.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/translate/translate_manager.cc')
-rw-r--r--chrome/browser/translate/translate_manager.cc253
1 files changed, 238 insertions, 15 deletions
diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc
index 214d731..3968de9 100644
--- a/chrome/browser/translate/translate_manager.cc
+++ b/chrome/browser/translate/translate_manager.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/translate/translate_manager.h"
+#include "app/resource_bundle.h"
#include "base/compiler_specific.h"
#include "base/string_util.h"
#include "chrome/browser/browser_process.h"
@@ -11,7 +12,6 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/renderer_host/render_process_host.h"
#include "chrome/browser/renderer_host/render_view_host.h"
-#include "chrome/browser/renderer_host/translation_service.h"
#include "chrome/browser/tab_contents/language_state.h"
#include "chrome/browser/tab_contents/navigation_controller.h"
#include "chrome/browser/tab_contents/navigation_entry.h"
@@ -24,9 +24,102 @@
#include "chrome/common/notification_source.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
+#include "grit/browser_resources.h"
+#include "net/url_request/url_request_status.h"
+
+namespace {
+
+// Mapping from a locale name to a language code name.
+// Locale names not included are translated as is.
+struct LocaleToCLDLanguage {
+ const char* locale_language; // Language Chrome locale is in.
+ const char* cld_language; // Language the CLD reports.
+};
+LocaleToCLDLanguage kLocaleToCLDLanguages[] = {
+ { "en-GB", "en" },
+ { "en-US", "en" },
+ { "es-419", "es" },
+ { "pt-BR", "pt" },
+ { "pt-PT", "pt" },
+};
+
+// The list of languages the Google translation server supports.
+// For information, here is the list of languages that Chrome can be run in
+// but that the translation server does not support:
+// am Amharic
+// bn Bengali
+// gu Gujarati
+// kn Kannada
+// ml Malayalam
+// mr Marathi
+// ta Tamil
+// te Telugu
+const char* kSupportedLanguages[] = {
+ "af", // Afrikaans
+ "sq", // Albanian
+ "ar", // Arabic
+ "be", // Belarusian
+ "bg", // Bulgarian
+ "ca", // Catalan
+ "zh-CN", // Chinese (Simplified)
+ "zh-TW", // Chinese (Traditional)
+ "hr", // Croatian
+ "cs", // Czech
+ "da", // Danish
+ "nl", // Dutch
+ "en", // English
+ "et", // Estonian
+ "fi", // Finnish
+ "fil", // Filipino
+ "fr", // French
+ "gl", // Galician
+ "de", // German
+ "el", // Greek
+ "he", // Hebrew
+ "hi", // Hindi
+ "hu", // Hungarian
+ "is", // Icelandic
+ "id", // Indonesian
+ "it", // Italian
+ "ga", // Irish
+ "ja", // Japanese
+ "ko", // Korean
+ "lv", // Latvian
+ "lt", // Lithuanian
+ "mk", // Macedonian
+ "ms", // Malay
+ "mt", // Maltese
+ "nb", // Norwegian
+ "fa", // Persian
+ "pl", // Polish
+ "pt", // Portuguese
+ "ro", // Romanian
+ "ru", // Russian
+ "sr", // Serbian
+ "sk", // Slovak
+ "sl", // Slovenian
+ "es", // Spanish
+ "sw", // Swahili
+ "sv", // Swedish
+ "th", // Thai
+ "tr", // Turkish
+ "uk", // Ukrainian
+ "vi", // Vietnamese
+ "cy", // Welsh
+ "yi", // Yiddish
+};
+
+const char* const kTranslateScriptURL =
+ "http://translate.google.com/translate_a/element.js?"
+ "cb=cr.googleTranslate.onTranslateElementLoad";
+const char* const kTranslateScriptHeader =
+ "Google-Translate-Element-Mode: library";
+
+} // namespace
// static
-bool TranslateManager::test_enabled_ = false;
+base::LazyInstance<std::set<std::string> >
+ TranslateManager::supported_languages_(base::LINKER_INITIALIZED);
TranslateManager::~TranslateManager() {
}
@@ -36,6 +129,34 @@ bool TranslateManager::IsTranslatableURL(const GURL& url) {
return !url.SchemeIs("chrome");
}
+// static
+void TranslateManager::GetSupportedLanguages(
+ std::vector<std::string>* languages) {
+ DCHECK(languages && languages->empty());
+ for (size_t i = 0; i < arraysize(kSupportedLanguages); ++i)
+ languages->push_back(kSupportedLanguages[i]);
+}
+
+// static
+std::string TranslateManager::GetLanguageCode(
+ const std::string& chrome_locale) {
+ for (size_t i = 0; i < arraysize(kLocaleToCLDLanguages); ++i) {
+ if (chrome_locale == kLocaleToCLDLanguages[i].locale_language)
+ return kLocaleToCLDLanguages[i].cld_language;
+ }
+ return chrome_locale;
+}
+
+// static
+bool TranslateManager::IsSupportedLanguage(const std::string& page_language) {
+ if (supported_languages_.Pointer()->empty()) {
+ for (size_t i = 0; i < arraysize(kSupportedLanguages); ++i)
+ supported_languages_.Pointer()->insert(kSupportedLanguages[i]);
+ }
+ return supported_languages_.Pointer()->find(page_language) !=
+ supported_languages_.Pointer()->end();
+}
+
void TranslateManager::Observe(NotificationType type,
const NotificationSource& source,
const NotificationDetails& details) {
@@ -135,6 +256,48 @@ void TranslateManager::Observe(NotificationType type,
}
}
+void TranslateManager::OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data) {
+ scoped_ptr<const URLFetcher> delete_ptr(source);
+ DCHECK(translate_script_request_pending_);
+ translate_script_request_pending_ = false;
+ if (status.status() != URLRequestStatus::SUCCESS || response_code != 200)
+ return; // We could not retrieve the translate script.
+
+ base::StringPiece str = ResourceBundle::GetSharedInstance().
+ GetRawDataResource(IDR_TRANSLATE_JS);
+ DCHECK(translate_script_.empty());
+ str.CopyToString(&translate_script_);
+ translate_script_ += "\n" + data;
+
+ // Execute any pending requests.
+ std::vector<PendingRequest>::const_iterator iter;
+ for (iter = pending_requests_.begin(); iter != pending_requests_.end();
+ ++iter) {
+ const PendingRequest& request = *iter;
+ TabContents* tab = tab_util::GetTabContentsByID(request.render_process_id,
+ request.render_view_id);
+ if (!tab) {
+ // The tab went away while we were retrieving the script.
+ continue;
+ }
+ NavigationEntry* entry = tab->controller().GetActiveEntry();
+ if (!entry || entry->page_id() != request.page_id) {
+ // We navigated away from the page the translation was triggered on.
+ continue;
+ }
+
+ // Translate the page.
+ DoTranslatePage(tab, translate_script_,
+ request.source_lang, request.target_lang);
+ }
+ pending_requests_.clear();
+}
+
// static
bool TranslateManager::IsShowingTranslateInfobar(TabContents* tab) {
for (int i = 0; i < tab->infobar_delegate_count(); ++i) {
@@ -145,10 +308,8 @@ bool TranslateManager::IsShowingTranslateInfobar(TabContents* tab) {
}
TranslateManager::TranslateManager()
- : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
- if (!test_enabled_ && !TranslationService::IsTranslationEnabled())
- return;
-
+ : ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)),
+ translate_script_request_pending_(false) {
notification_registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
NotificationService::AllSources());
notification_registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED,
@@ -172,8 +333,7 @@ void TranslateManager::InitiateTranslation(TabContents* tab,
std::string target_lang = GetTargetLanguage();
// Nothing to do if either the language Chrome is in or the language of the
// page is not supported by the translation server.
- if (target_lang.empty() ||
- !TranslationService::IsSupportedLanguage(page_lang)) {
+ if (target_lang.empty() || !IsSupportedLanguage(page_lang)) {
return;
}
@@ -194,14 +354,14 @@ void TranslateManager::InitiateTranslation(TabContents* tab,
// page's text is sent to the translate server.
if (TranslatePrefs::ShouldAutoTranslate(prefs, page_lang, target_lang) &&
!tab->profile()->IsOffTheRecord()) {
- tab->TranslatePage(page_lang, target_lang);
+ TranslatePage(tab, page_lang, target_lang);
return;
}
std::string auto_translate_to = tab->language_state().AutoTranslateTo();
if (!auto_translate_to.empty()) {
// This page was navigated through a click from a translated page.
- tab->TranslatePage(page_lang, auto_translate_to);
+ TranslatePage(tab, page_lang, auto_translate_to);
return;
}
@@ -222,6 +382,57 @@ void TranslateManager::InitiateTranslationPosted(int process_id,
InitiateTranslation(tab, page_lang);
}
+void TranslateManager::TranslatePage(TabContents* tab_contents,
+ const std::string& source_lang,
+ const std::string& target_lang) {
+ NavigationEntry* entry = tab_contents->controller().GetActiveEntry();
+ if (!entry) {
+ NOTREACHED();
+ return;
+ }
+ if (!translate_script_.empty()) {
+ DoTranslatePage(tab_contents, translate_script_, source_lang, target_lang);
+ return;
+ }
+
+ // The script is not available yet. Queue that request and query for the
+ // script. Once it is downloaded we'll do the translate.
+ RenderViewHost* rvh = tab_contents->render_view_host();
+ PendingRequest request;
+ request.render_process_id = rvh->process()->id();
+ request.render_view_id = rvh->routing_id();
+ request.page_id = entry->page_id();
+ request.source_lang = source_lang;
+ request.target_lang = target_lang;
+ pending_requests_.push_back(request);
+ RequestTranslateScript();
+}
+
+void TranslateManager::RevertTranslation(TabContents* tab_contents) {
+ NavigationEntry* entry = tab_contents->controller().GetActiveEntry();
+ if (!entry) {
+ NOTREACHED();
+ return;
+ }
+ tab_contents->render_view_host()->RevertTranslation(entry->page_id());
+}
+
+void TranslateManager::DoTranslatePage(TabContents* tab_contents,
+ const std::string& translate_script,
+ const std::string& source_lang,
+ const std::string& target_lang) {
+ NavigationEntry* entry = tab_contents->controller().GetActiveEntry();
+ if (!entry) {
+ NOTREACHED();
+ return;
+ }
+
+ tab_contents->language_state().set_translation_pending(true);
+ tab_contents->render_view_host()->TranslatePage(entry->page_id(),
+ translate_script,
+ source_lang, target_lang);
+}
+
bool TranslateManager::IsAcceptLanguage(TabContents* tab,
const std::string& language) {
PrefService* pref_service = tab->profile()->GetPrefs();
@@ -249,8 +460,8 @@ void TranslateManager::InitAcceptLanguages(PrefService* prefs) {
LanguageSet accept_langs_set;
SplitString(WideToASCII(accept_langs_str), ',', &accept_langs_list);
std::vector<std::string>::const_iterator iter;
- std::string ui_lang = TranslationService::GetLanguageCode(
- g_browser_process->GetApplicationLocale());
+ std::string ui_lang =
+ GetLanguageCode(g_browser_process->GetApplicationLocale());
bool is_ui_english = StartsWithASCII(ui_lang, "en-", false);
for (iter = accept_langs_list.begin();
iter != accept_langs_list.end(); ++iter) {
@@ -273,6 +484,18 @@ void TranslateManager::InitAcceptLanguages(PrefService* prefs) {
accept_languages_[prefs] = accept_langs_set;
}
+void TranslateManager::RequestTranslateScript() {
+ if (translate_script_request_pending_)
+ return;
+
+ translate_script_request_pending_ = true;
+ URLFetcher* fetcher = URLFetcher::Create(0, GURL(kTranslateScriptURL),
+ URLFetcher::GET, this);
+ fetcher->set_request_context(Profile::GetDefaultRequestContext());
+ fetcher->set_extra_request_headers(kTranslateScriptHeader);
+ fetcher->Start();
+}
+
// static
void TranslateManager::AddTranslateInfoBar(
TabContents* tab, TranslateInfoBarDelegate::TranslateState state,
@@ -294,9 +517,9 @@ void TranslateManager::AddTranslateInfoBar(
// static
std::string TranslateManager::GetTargetLanguage() {
- std::string target_lang = TranslationService::GetLanguageCode(
- g_browser_process->GetApplicationLocale());
- if (TranslationService::IsSupportedLanguage(target_lang))
+ std::string target_lang =
+ GetLanguageCode(g_browser_process->GetApplicationLocale());
+ if (IsSupportedLanguage(target_lang))
return target_lang;
return std::string();
}