summaryrefslogtreecommitdiffstats
path: root/chrome/browser/translate
diff options
context:
space:
mode:
authorjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-06 22:21:02 +0000
committerjcivelli@google.com <jcivelli@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-06 22:21:02 +0000
commit85d252e22b6bec161873a0b5656d59c8ebe04e30 (patch)
tree937f8add8eac344f93d6a8ec6604796f371c761c /chrome/browser/translate
parentd41661b5e24c8d774acea07c05ef2e5896587e56 (diff)
downloadchromium_src-85d252e22b6bec161873a0b5656d59c8ebe04e30.zip
chromium_src-85d252e22b6bec161873a0b5656d59c8ebe04e30.tar.gz
chromium_src-85d252e22b6bec161873a0b5656d59c8ebe04e30.tar.bz2
Changing the translate back-end to use the Google Translate element.
When the user indicates that a page should be translated, the browser first fetches the Google Translate Element JS code. It then sends it to the renderer, which injects the script in the page, waits for the Translate element to be initialized and then calls the translate method on it. The TranslationService class previously used to translate text chunks is now unused and has been removed. Some of its static methods that are still used have been moved to the TranslateManager class. This CL also implements the "revert" translation behavior. BUG=35474,37778,35553,39375 TEST=Test the translation feature extensively. Review URL: http://codereview.chromium.org/1599016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43768 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/translate')
-rw-r--r--chrome/browser/translate/translate_infobars_delegates.cc20
-rw-r--r--chrome/browser/translate/translate_manager.cc253
-rw-r--r--chrome/browser/translate/translate_manager.h77
-rw-r--r--chrome/browser/translate/translate_manager_unittest.cc74
4 files changed, 382 insertions, 42 deletions
diff --git a/chrome/browser/translate/translate_infobars_delegates.cc b/chrome/browser/translate/translate_infobars_delegates.cc
index 5caff33..0f66357 100644
--- a/chrome/browser/translate/translate_infobars_delegates.cc
+++ b/chrome/browser/translate/translate_infobars_delegates.cc
@@ -7,8 +7,8 @@
#include "app/l10n_util.h"
#include "app/resource_bundle.h"
#include "chrome/browser/browser_process.h"
-#include "chrome/browser/renderer_host/translation_service.h"
#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/translate/translate_manager.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
@@ -68,12 +68,12 @@ void TranslateInfoBarDelegate::ModifyTargetLanguage(int lang_index) {
void TranslateInfoBarDelegate::GetAvailableOriginalLanguages(
std::vector<std::string>* languages) {
- TranslationService::GetSupportedLanguages(languages);
+ TranslateManager::GetSupportedLanguages(languages);
}
void TranslateInfoBarDelegate::GetAvailableTargetLanguages(
std::vector<std::string>* languages) {
- TranslationService::GetSupportedLanguages(languages);
+ TranslateManager::GetSupportedLanguages(languages);
}
void TranslateInfoBarDelegate::Translate() {
@@ -81,11 +81,14 @@ void TranslateInfoBarDelegate::Translate() {
// are different, so only in this case is translation really pending.
if (original_lang_index_ != target_lang_index_)
translation_pending_ = true;
- tab_contents_->TranslatePage(original_lang_code(), target_lang_code());
+ Singleton<TranslateManager>::get()->TranslatePage(tab_contents_,
+ original_lang_code(),
+ target_lang_code());
}
void TranslateInfoBarDelegate::RevertTranslation() {
- tab_contents_->RevertTranslatedPage();
+ Singleton<TranslateManager>::get()->RevertTranslation(tab_contents_);
+ tab_contents_->RemoveInfoBar(this);
}
void TranslateInfoBarDelegate::TranslationDeclined() {
@@ -177,7 +180,8 @@ string16 TranslateInfoBarDelegate::GetErrorMessage(
case TranslateErrors::NETWORK:
message_id = IDS_TRANSLATE_INFOBAR_ERROR_CANT_CONNECT;
break;
- case TranslateErrors::SERVER:
+ case TranslateErrors::INITIALIZATION_ERROR:
+ case TranslateErrors::TRANSLATION_ERROR:
message_id = IDS_TRANSLATE_INFOBAR_ERROR_CANT_TRANSLATE;
break;
default:
@@ -196,7 +200,7 @@ TranslateInfoBarDelegate* TranslateInfoBarDelegate::Create(
const std::string& target_lang_code,
TranslateErrors::Type error_type) {
std::vector<std::string> supported_languages;
- TranslationService::GetSupportedLanguages(&supported_languages);
+ TranslateManager::GetSupportedLanguages(&supported_languages);
int original_lang_index = -1;
for (size_t i = 0; i < supported_languages.size(); ++i) {
@@ -241,7 +245,7 @@ TranslateInfoBarDelegate::TranslateInfoBarDelegate(TabContents* tab_contents,
never_translate_site_(false),
always_translate_(false),
error_type_(error_type) {
- TranslationService::GetSupportedLanguages(&supported_languages_);
+ TranslateManager::GetSupportedLanguages(&supported_languages_);
DCHECK(original_lang_index_ > -1);
DCHECK(target_lang_index_ > -1);
}
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();
}
diff --git a/chrome/browser/translate/translate_manager.h b/chrome/browser/translate/translate_manager.h
index cf0e452..5c7bbb2 100644
--- a/chrome/browser/translate/translate_manager.h
+++ b/chrome/browser/translate/translate_manager.h
@@ -8,9 +8,12 @@
#include <map>
#include <set>
#include <string>
+#include <vector>
+#include "base/lazy_instance.h"
#include "base/singleton.h"
#include "base/task.h"
+#include "chrome/browser/net/url_fetcher.h"
#include "chrome/browser/translate/translate_infobars_delegates.h"
#include "chrome/common/notification_observer.h"
#include "chrome/common/notification_registrar.h"
@@ -25,7 +28,8 @@ class TabContents;
// page translation the user requests.
// It is a singleton.
-class TranslateManager : public NotificationObserver {
+class TranslateManager : public NotificationObserver,
+ public URLFetcher::Delegate {
public:
virtual ~TranslateManager();
@@ -34,6 +38,29 @@ class TranslateManager : public NotificationObserver {
const NotificationSource& source,
const NotificationDetails& details);
+ // URLFetcher::Delegate implementation:
+ virtual void OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data);
+
+ // Translates the page contents from |source_lang| to |target_lang|.
+ // The actual translation might be performed asynchronously if the translate
+ // script is not yet available.
+ void TranslatePage(TabContents* tab_contents,
+ const std::string& source_lang,
+ const std::string& target_lang);
+
+ // Reverts the contents of the page in |tab_contents| to its original
+ // language.
+ void RevertTranslation(TabContents* tab_contents);
+
+ // Clears the translate script, so it will be fetched next time we translate.
+ // Currently used by unit-tests.
+ void ClearTranslateScript() { translate_script_.clear(); }
+
// Convenience method to know if a tab is showing a translate infobar.
static bool IsShowingTranslateInfobar(TabContents* tab);
@@ -41,9 +68,16 @@ class TranslateManager : public NotificationObserver {
// (chrome:// and others).
static bool IsTranslatableURL(const GURL& url);
- // Used by unit-test to enable the TranslateManager for testing purpose.
- static void set_test_enabled(bool enabled) { test_enabled_ = enabled; }
- static bool test_enabled() { return test_enabled_; }
+ // Fills |languages| with the list of languages that the translate server can
+ // translate to and from.
+ static void GetSupportedLanguages(std::vector<std::string>* languages);
+
+ // Returns the language code that can be used with the Translate method for a
+ // specified |chrome_locale|.
+ static std::string GetLanguageCode(const std::string& chrome_locale);
+
+ // Returns true if |page_language| is supported by the translation server.
+ static bool IsSupportedLanguage(const std::string& page_language);
protected:
TranslateManager();
@@ -51,6 +85,17 @@ class TranslateManager : public NotificationObserver {
private:
friend struct DefaultSingletonTraits<TranslateManager>;
+ // Structure that describes a translate request.
+ // Translation may be deferred while the translate script is being retrieved
+ // from the translate server.
+ struct PendingRequest {
+ int render_process_id;
+ int render_view_id;
+ int page_id;
+ std::string source_lang;
+ std::string target_lang;
+ };
+
// Starts the translation process on |tab| containing the page in the
// |page_lang| language.
void InitiateTranslation(TabContents* tab, const std::string& page_lang);
@@ -61,6 +106,12 @@ class TranslateManager : public NotificationObserver {
int render_id,
const std::string& page_lang);
+ // Sends a translation request to the RenderView of |tab_contents|.
+ void DoTranslatePage(TabContents* tab_contents,
+ const std::string& translate_script,
+ const std::string& source_lang,
+ const std::string& target_lang);
+
// Returns true if the passed language has been configured by the user as an
// accept language.
bool IsAcceptLanguage(TabContents* tab, const std::string& language);
@@ -69,6 +120,10 @@ class TranslateManager : public NotificationObserver {
// preference in |prefs|.
void InitAcceptLanguages(PrefService* prefs);
+ // Fetches the JS translate script (the script that is injected in the page
+ // to translate it).
+ void RequestTranslateScript();
+
// Convenience method that adds a translate infobar to |tab|.
static void AddTranslateInfoBar(
TabContents* tab,
@@ -92,7 +147,19 @@ class TranslateManager : public NotificationObserver {
ScopedRunnableMethodFactory<TranslateManager> method_factory_;
- static bool test_enabled_;
+ // The JS injected in the page to do the translation.
+ std::string translate_script_;
+
+ // Whether the translate JS is currently being retrieved.
+ bool translate_script_request_pending_;
+
+ // The list of pending translate requests. Translate requests are queued when
+ // the translate script is not ready and has to be fetched from the translate
+ // server.
+ std::vector<PendingRequest> pending_requests_;
+
+ // The languages supported by the translation server.
+ static base::LazyInstance<std::set<std::string> > supported_languages_;
DISALLOW_COPY_AND_ASSIGN(TranslateManager);
};
diff --git a/chrome/browser/translate/translate_manager_unittest.cc b/chrome/browser/translate/translate_manager_unittest.cc
index bc0924c..e543af0 100644
--- a/chrome/browser/translate/translate_manager_unittest.cc
+++ b/chrome/browser/translate/translate_manager_unittest.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/renderer_host/test/test_render_view_host.h"
+#include "chrome/browser/net/test_url_fetcher_factory.h"
#include "chrome/browser/renderer_host/mock_render_process_host.h"
#include "chrome/browser/tab_contents/render_view_context_menu.h"
#include "chrome/browser/translate/translate_infobars_delegates.h"
@@ -50,11 +51,15 @@ class TranslateManagerTest : public RenderViewHostTestHarness,
process()->sink().GetFirstMessageMatching(ViewMsg_TranslatePage::ID);
if (!message)
return false;
- Tuple3<int, std::string, std::string> translate_param;
+ Tuple4<int, std::string, std::string, std::string> translate_param;
ViewMsg_TranslatePage::Read(message, &translate_param);
- *page_id = translate_param.a;
- *original_lang = translate_param.b;
- *target_lang = translate_param.c;
+ if (page_id)
+ *page_id = translate_param.a;
+ // Ignore translate_param.b which is the script injected in the page.
+ if (original_lang)
+ *original_lang = translate_param.c;
+ if (target_lang)
+ *target_lang = translate_param.d;
return true;
}
@@ -111,15 +116,15 @@ class TranslateManagerTest : public RenderViewHostTestHarness,
protected:
virtual void SetUp() {
- TranslateManager::set_test_enabled(true);
- // This must be created after set_test_enabled() has been called to register
- // notifications properly. Note that we do this before calling
+ URLFetcher::set_factory(&url_fetcher_factory_);
+
+ // Access the TranslateManager singleton so it is created before we call
// RenderViewHostTestHarness::SetUp() to match what's done in Chrome, where
- // the TranslateManager is created before the TabContents. This matters for
- // as they both register for similar events and we want the notifications
- // to happen in the same sequence (TranslateManager first, TabContents
- // second).
- translate_manager_.reset(new TestTranslateManager());
+ // the TranslateManager is created before the TabContents. This matters as
+ // they both register for similar events and we want the notifications to
+ // happen in the same sequence (TranslateManager first, TabContents second).
+ // Also clears the translate script so it is fetched everytime.
+ Singleton<TranslateManager>::get()->ClearTranslateScript();
RenderViewHostTestHarness::SetUp();
@@ -137,13 +142,25 @@ class TranslateManagerTest : public RenderViewHostTestHarness,
RenderViewHostTestHarness::TearDown();
- TranslateManager::set_test_enabled(false);
+ URLFetcher::set_factory(NULL);
+ }
+
+ void SimulateURLFetch(bool success) {
+ TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
+ ASSERT_TRUE(fetcher);
+ URLRequestStatus status;
+ status.set_status(success ? URLRequestStatus::SUCCESS :
+ URLRequestStatus::FAILED);
+ fetcher->delegate()->OnURLFetchComplete(fetcher, fetcher->original_url(),
+ status, success ? 200 : 500,
+ ResponseCookies(),
+ std::string());
}
private:
NotificationRegistrar notification_registrar_;
-
scoped_ptr<TestTranslateManager> translate_manager_;
+ TestURLFetcherFactory url_fetcher_factory_;
// The list of infobars that have been removed.
// WARNING: the pointers points to deleted objects, use only for comparison.
@@ -251,6 +268,9 @@ TEST_F(TranslateManagerTest, NormalTranslate) {
// Simulate clicking translate.
process()->sink().ClearMessages();
infobar->Translate();
+ // Simulate the translate script being retrieved (it only needs to be done
+ // once in the test as it is cached).
+ SimulateURLFetch(true);
EXPECT_FALSE(InfoBarRemoved());
// Test that we sent the right message to the renderer.
@@ -297,6 +317,26 @@ TEST_F(TranslateManagerTest, NormalTranslate) {
EXPECT_EQ(new_target_lang, target_lang);
}
+TEST_F(TranslateManagerTest, TranslateScriptNotAvailable) {
+ // Simulate navigating to a page.
+ SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
+
+ // We should have an info-bar.
+ TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
+ ASSERT_TRUE(infobar != NULL);
+ EXPECT_EQ(TranslateInfoBarDelegate::kBeforeTranslate, infobar->state());
+
+ // Simulate clicking translate.
+ process()->sink().ClearMessages();
+ infobar->Translate();
+ // Simulate a failure retrieving the translate script.
+ SimulateURLFetch(false);
+ EXPECT_FALSE(InfoBarRemoved());
+
+ // We should not have sent any message to translate to the renderer.
+ EXPECT_FALSE(GetTranslateMessage(NULL, NULL, NULL));
+}
+
// Tests that we show/don't show an info-bar for all languages the CLD can
// report.
TEST_F(TranslateManagerTest, TestAllLanguages) {
@@ -376,6 +416,8 @@ TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) {
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
infobar->Translate();
+ SimulateURLFetch(true); // Simulate the translate script being retrieved.
+
rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en",
TranslateErrors::NONE));
@@ -519,6 +561,7 @@ TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) {
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
infobar->Translate();
+ SimulateURLFetch(true); // Simulate the translate script being retrieved.
rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en",
TranslateErrors::NONE));
@@ -547,6 +590,7 @@ TEST_F(TranslateManagerTest, TranslateInPageNavigation) {
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
infobar->Translate();
+ SimulateURLFetch(true); // Simulate the translate script being retrieved.
rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en",
TranslateErrors::NONE));
@@ -711,6 +755,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) {
SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr");
// It should have triggered an automatic translation to English.
+ SimulateURLFetch(true); // Simulate the translate script being retrieved.
int page_id = 0;
std::string original_lang, target_lang;
EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
@@ -769,6 +814,7 @@ TEST_F(TranslateManagerTest, ContextMenu) {
menu->TestExecuteItemCommand(IDS_CONTENT_CONTEXT_TRANSLATE);
// That should have triggered a translation.
+ SimulateURLFetch(true); // Simulate the translate script being retrieved.
int page_id = 0;
std::string original_lang, target_lang;
EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang));