diff options
Diffstat (limited to 'chrome/browser/translate/translate_manager.cc')
-rw-r--r-- | chrome/browser/translate/translate_manager.cc | 253 |
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(); } |