diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-12 21:53:55 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-12 21:53:55 +0000 |
commit | 3b1c18191d41eac0a551b3009269a259757ca070 (patch) | |
tree | 5f466b716abc81ac3bb67262522ba1af0d699588 /chrome | |
parent | 7d9ad0b30c0775a7345e965294c9f86bb0d543e5 (diff) | |
download | chromium_src-3b1c18191d41eac0a551b3009269a259757ca070.zip chromium_src-3b1c18191d41eac0a551b3009269a259757ca070.tar.gz chromium_src-3b1c18191d41eac0a551b3009269a259757ca070.tar.bz2 |
Implements the auto-translate on click: if you have translated
a page and are navigating to a new page in the same language by
clicking a link, the new page is automatically translated.
In order to do that I moved the language state from the navigation
entry to some dedicated class that each TabContents owns.
Also added some basic unit-testing for good measure.
BUG=35477
TEST=See bug steps. Run unit-tests.
Review URL: http://codereview.chromium.org/596092
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@38961 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/browser_browsertest.cc | 12 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_tabs_module.cc | 17 | ||||
-rw-r--r-- | chrome/browser/renderer_host/test/test_render_view_host.h | 4 | ||||
-rw-r--r-- | chrome/browser/tab_contents/language_state.cc | 51 | ||||
-rw-r--r-- | chrome/browser/tab_contents/language_state.h | 84 | ||||
-rw-r--r-- | chrome/browser/tab_contents/navigation_entry.h | 10 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.cc | 15 | ||||
-rw-r--r-- | chrome/browser/tab_contents/tab_contents.h | 8 | ||||
-rw-r--r-- | chrome/browser/translate/translate_manager.cc | 36 | ||||
-rw-r--r-- | chrome/browser/translate/translate_manager.h | 9 | ||||
-rw-r--r-- | chrome/browser/translate/translate_manager_unittest.cc | 142 | ||||
-rwxr-xr-x | chrome/chrome_browser.gypi | 2 | ||||
-rwxr-xr-x | chrome/chrome_tests.gypi | 1 |
13 files changed, 328 insertions, 63 deletions
diff --git a/chrome/browser/browser_browsertest.cc b/chrome/browser/browser_browsertest.cc index fcd063d..edce8e0 100644 --- a/chrome/browser/browser_browsertest.cc +++ b/chrome/browser/browser_browsertest.cc @@ -457,20 +457,16 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, PageLanguageDetection) { // Navigate to a page in English. ui_test_utils::NavigateToURL( browser(), GURL(server->TestServerPage("files/english_page.html"))); - NavigationEntry* entry = current_tab->controller().GetActiveEntry(); - ASSERT_TRUE(NULL != entry); - EXPECT_TRUE(entry->language().empty()); + EXPECT_TRUE(current_tab->language_state().original_language().empty()); std::string lang = ui_test_utils::WaitForLanguageDetection(current_tab); EXPECT_EQ("en", lang); - EXPECT_EQ("en", entry->language()); + EXPECT_EQ("en", current_tab->language_state().original_language()); // Now navigate to a page in French. ui_test_utils::NavigateToURL( browser(), GURL(server->TestServerPage("files/french_page.html"))); - entry = current_tab->controller().GetActiveEntry(); - ASSERT_TRUE(NULL != entry); - EXPECT_TRUE(entry->language().empty()); + EXPECT_TRUE(current_tab->language_state().original_language().empty()); lang = ui_test_utils::WaitForLanguageDetection(current_tab); EXPECT_EQ("fr", lang); - EXPECT_EQ("fr", entry->language()); + EXPECT_EQ("fr", current_tab->language_state().original_language()); } diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index f85f054..14621bf 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -883,16 +883,13 @@ bool DetectTabLanguageFunction::RunImpl() { AddRef(); // Balanced in GotLanguage() - NavigationEntry* entry = contents->controller().GetActiveEntry(); - if (entry) { - std::string language = entry->language(); - if (!language.empty()) { - // Delay the callback invocation until after the current JS call has - // returned. - MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( - this, &DetectTabLanguageFunction::GotLanguage, language)); - return true; - } + if (!contents->language_state().original_language().empty()) { + // Delay the callback invocation until after the current JS call has + // returned. + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( + this, &DetectTabLanguageFunction::GotLanguage, + contents->language_state().original_language())); + return true; } // The tab contents does not know its language yet. Let's wait until it // receives it, or until the tab is closed/navigates to some other page. diff --git a/chrome/browser/renderer_host/test/test_render_view_host.h b/chrome/browser/renderer_host/test/test_render_view_host.h index 85e6eca..d2cac6e 100644 --- a/chrome/browser/renderer_host/test/test_render_view_host.h +++ b/chrome/browser/renderer_host/test/test_render_view_host.h @@ -246,8 +246,8 @@ class RenderViewHostTestHarness : public testing::Test { contents_.reset(); } - // Creates a pending navigation to the given oURL with the default parameters - // and the commits the load with a page ID one larger than any seen. This + // Creates a pending navigation to the given URL with the default parameters + // and then commits the load with a page ID one larger than any seen. This // emulates what happens on a new navigation. void NavigateAndCommit(const GURL& url); diff --git a/chrome/browser/tab_contents/language_state.cc b/chrome/browser/tab_contents/language_state.cc new file mode 100644 index 0000000..8522ed3 --- /dev/null +++ b/chrome/browser/tab_contents/language_state.cc @@ -0,0 +1,51 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/tab_contents/language_state.h" + +#include "chrome/browser/tab_contents/navigation_controller.h" +#include "chrome/browser/tab_contents/navigation_entry.h" + +LanguageState::LanguageState(NavigationController* nav_controller) + : navigation_controller_(nav_controller), + translation_pending_(false) { +} + +LanguageState::~LanguageState() { +} + +void LanguageState::DidNavigate() { + prev_original_lang_ = original_lang_; + prev_current_lang_ = current_lang_; + + original_lang_.clear(); + current_lang_.clear(); + + translation_pending_ = false; +} + +void LanguageState::LanguageDetermined(const std::string& page_language) { + original_lang_ = page_language; + current_lang_ = page_language; +} + +std::string LanguageState::AutoTranslateTo() const { + // Only auto-translate if: + // - no translation is pending + // - this page is in the same language as the previous page + // - the previous page had been translated + // - this page is not already translated + // - the new page was navigated through a link. + if (!translation_pending_ && + prev_original_lang_ == original_lang_ && + prev_original_lang_ != prev_current_lang_ && + original_lang_ == current_lang_ && + navigation_controller_->GetActiveEntry() && + navigation_controller_->GetActiveEntry()->transition_type() == + PageTransition::LINK) { + return prev_current_lang_; + } + + return std::string(); +} diff --git a/chrome/browser/tab_contents/language_state.h b/chrome/browser/tab_contents/language_state.h new file mode 100644 index 0000000..d5c7df6 --- /dev/null +++ b/chrome/browser/tab_contents/language_state.h @@ -0,0 +1,84 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ +#define CHROME_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ + +#include <string> + +#include "base/basictypes.h" + +class NavigationController; + +// This class holds the language state of the current page. +// There is one LanguageState instance per TabContents. +// It is used to determine when navigating to a new page whether it should +// automatically be translated. +// This auto-translate behavior is the expected behavior when: +// - user is on page in language A that they had translated to language B. +// - user clicks a link in that page that takes them to a page also in language +// A. + +class LanguageState { + public: + explicit LanguageState(NavigationController* nav_controller); + ~LanguageState(); + + // Should be called when the page did a new navigation (whether it is a main + // frame or sub-frame navigation). + void DidNavigate(); + + // Should be called when the language of the page has been determined. + void LanguageDetermined(const std::string& page_language); + + // Returns the language the current page should be translated to, based on the + // previous page languages and the transition. This should be called after + // the language page has been determined. + // Returns an empty string if the page should not be auto-translated. + std::string AutoTranslateTo() const; + + // Returns true if the current page in the associated tab has been translated. + bool IsPageTranslated() const { return original_lang_ != current_lang_; } + + const std::string& original_language() const { return original_lang_; } + + void set_current_language(const std::string& language) { + current_lang_ = language; + } + const std::string& current_language() const { return current_lang_; } + + // Whether the page is currently in the process of being translated. + bool translation_pending() const { return translation_pending_; } + void set_translation_pending(bool value) { translation_pending_ = value; } + + private: + // The languages this page is in. Note that current_lang_ is different from + // original_lang_ when the page has been translated. + // Note that these might be empty if the page language has not been determined + // yet. + std::string original_lang_; + std::string current_lang_; + + // Same as above but for the previous page. + std::string prev_original_lang_; + std::string prev_current_lang_; + + // The navigation controller of the tab we are associated with. + NavigationController* navigation_controller_; + + // Whether a translation is currently pending (TabContents waiting for the + // PAGE_TRANSLATED notification). This is needed to avoid sending duplicate + // translate requests to a page. TranslateManager initiates translations + // when it received the LANGUAGE_DETERMINED notification. This is sent by + // the renderer with the page contents, every time the load stops for the + // main frame, so we may get several. + // TODO(jcampan): make the renderer send the language just once per navigation + // then we can get rid of that state. + bool translation_pending_; + + DISALLOW_COPY_AND_ASSIGN(LanguageState); +}; + +#endif // CHROME_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ + diff --git a/chrome/browser/tab_contents/navigation_entry.h b/chrome/browser/tab_contents/navigation_entry.h index df6ad06..e679c10 100644 --- a/chrome/browser/tab_contents/navigation_entry.h +++ b/chrome/browser/tab_contents/navigation_entry.h @@ -389,15 +389,6 @@ class NavigationEntry { return restore_type_; } - // The ISO 639-1 language code (ex: en, fr, zh...) for the page. - // Can be empty if the language was not detected yet or is unknown. - void set_language(const std::string& language) { - language_ = language; - } - std::string language() const { - return language_; - } - private: // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING // Session/Tab restore save portions of this class so that it can be recreated @@ -422,7 +413,6 @@ class NavigationEntry { GURL user_typed_url_; bool has_post_data_; RestoreType restore_type_; - std::string language_; // ISO 639-1 language code. // This is a cached version of the result of GetTitleForDisplay. It prevents // us from having to do URL formatting on the URL evey time the title is diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index 2f0dcd9..ed15084 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -269,7 +269,8 @@ TabContents::TabContents(Profile* profile, is_showing_before_unload_dialog_(false), renderer_preferences_(), opener_dom_ui_type_(DOMUIFactory::kNoDOMUI), - app_extension_(NULL) { + app_extension_(NULL), + language_state_(&controller_) { ClearBlockedContentSettings(); renderer_preferences_util::UpdateFromSystemSettings( &renderer_preferences_, profile); @@ -811,6 +812,7 @@ void TabContents::TranslatePage(const std::string& source_lang, NOTREACHED(); return; } + language_state_.set_translation_pending(true); render_view_host()->TranslatePage(entry->page_id(), source_lang, target_lang); } @@ -1503,6 +1505,9 @@ void TabContents::DidNavigateAnyFramePostCommit( // cleaned up and covered by tests. if (params.password_form.origin.is_valid()) GetPasswordManager()->ProvisionallySavePassword(params.password_form); + + // Let the LanguageState clear its state. + language_state_.DidNavigate(); } void TabContents::CloseConstrainedWindows() { @@ -1860,11 +1865,7 @@ void TabContents::OnPageContents(const GURL& url, } } - NavigationEntry* entry = controller_.GetActiveEntry(); - if (GetRenderProcessHost()->id() == renderer_process_id && - entry && entry->page_id() == page_id) { - entry->set_language(language); - } + language_state_.LanguageDetermined(language); std::string lang = language; NotificationService::current()->Notify( @@ -1876,6 +1877,8 @@ void TabContents::OnPageContents(const GURL& url, void TabContents::OnPageTranslated(int32 page_id, const std::string& original_lang, const std::string& translated_lang) { + language_state_.set_current_language(translated_lang); + language_state_.set_translation_pending(false); std::pair<std::string, std::string> lang_pair = std::make_pair(original_lang, translated_lang); NotificationService::current()->Notify( diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 2c7e5be..4d11745 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -30,6 +30,7 @@ #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/tab_contents/constrained_window.h" #include "chrome/browser/tab_contents/infobar_delegate.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" #include "chrome/browser/tab_contents/page_navigator.h" @@ -639,6 +640,10 @@ class TabContents : public PageNavigator, return request_context_; } + LanguageState& language_state() { + return language_state_; + } + // Creates a duplicate of this TabContents. The returned TabContents is // configured such that the renderer has not been loaded (it'll load the first // time it is selected). @@ -1180,6 +1185,9 @@ class TabContents : public PageNavigator, // created for. Extension* app_extension_; + // Information about the language the page is in and has been translated to. + LanguageState language_state_; + // --------------------------------------------------------------------------- DISALLOW_COPY_AND_ASSIGN(TabContents); diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc index 5f24cb6..773c066 100644 --- a/chrome/browser/translate/translate_manager.cc +++ b/chrome/browser/translate/translate_manager.cc @@ -8,6 +8,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/profile.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" #include "chrome/browser/tab_contents/tab_contents.h" @@ -27,22 +28,13 @@ void TranslateManager::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { switch (type.value) { - case NotificationType::NAV_ENTRY_COMMITTED: { - // We have navigated to a new page. - NavigationController* controller = - Source<NavigationController>(source).ptr(); - NavigationEntry* entry = controller->GetActiveEntry(); - if (!entry->language().empty()) { - // The language for that page is known (it must be a back/forward - // navigation to a page we already visited). - InitiateTranslation(controller->tab_contents(), entry->language()); - } - break; - } case NotificationType::TAB_LANGUAGE_DETERMINED: { TabContents* tab = Source<TabContents>(source).ptr(); std::string language = *(Details<std::string>(details).ptr()); - InitiateTranslation(tab, language); + // We may get this notifications multiple times. Make sure to translate + // only once. + if (!tab->language_state().translation_pending()) + InitiateTranslation(tab, language); break; } case NotificationType::PAGE_TRANSLATED: { @@ -91,11 +83,9 @@ void TranslateManager::Observe(NotificationType type, } TranslateManager::TranslateManager() { - if (!TranslationService::IsTranslationEnabled()) + if (TestEnabled() && !TranslationService::IsTranslationEnabled()) return; - notification_registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, - NotificationService::AllSources()); notification_registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, NotificationService::AllSources()); notification_registrar_.Add(this, NotificationType::PAGE_TRANSLATED, @@ -134,15 +124,11 @@ void TranslateManager::InitiateTranslation(TabContents* tab, return; } - // If we already have an "after translate" infobar, it sometimes might be - // sticky when running in frames. So we need to proactively remove any - // translate related infobars as they would prevent any new infobar from - // showing. (As TabContents will not add an infobar if there is already one - // showing equal to the one being added.) - for (int i = tab->infobar_delegate_count() - 1; i >= 0; --i) { - InfoBarDelegate* info_bar = tab->GetInfoBarDelegateAt(i); - if (info_bar->AsTranslateInfoBarDelegate()) - tab->RemoveInfoBar(info_bar); + 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); + return; } // Prompts the user if he/she wants the page translated. diff --git a/chrome/browser/translate/translate_manager.h b/chrome/browser/translate/translate_manager.h index b70db4b..e41fb04 100644 --- a/chrome/browser/translate/translate_manager.h +++ b/chrome/browser/translate/translate_manager.h @@ -29,11 +29,16 @@ class TranslateManager : public NotificationObserver { virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); - private: - friend struct DefaultSingletonTraits<TranslateManager>; + + protected: + // Overriden by unit-tests to enable the TranslateManager. + virtual bool TestEnabled() { return false; } TranslateManager(); + private: + friend struct DefaultSingletonTraits<TranslateManager>; + // Starts the translation process on |tab| containing the page in the // |page_lang| language. void InitiateTranslation(TabContents* tab, const std::string& page_lang); diff --git a/chrome/browser/translate/translate_manager_unittest.cc b/chrome/browser/translate/translate_manager_unittest.cc new file mode 100644 index 0000000..75420c5 --- /dev/null +++ b/chrome/browser/translate/translate_manager_unittest.cc @@ -0,0 +1,142 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/renderer_host/test/test_render_view_host.h" + +#include "chrome/browser/renderer_host/mock_render_process_host.h" +#include "chrome/browser/translate/translate_infobars_delegates.h" +#include "chrome/browser/translate/translate_manager.h" +#include "chrome/common/ipc_test_sink.h" +#include "chrome/common/render_messages.h" + +class TestTranslateManager : public TranslateManager { + public: + TestTranslateManager() {} + + protected: + virtual bool TestEnabled() { return true; } +}; + +class TranslateManagerTest : public RenderViewHostTestHarness { + public: + // Simluates navigating to a page and getting teh page contents and language + // for that navigation. + void SimulateNavigation(const GURL& url, int page_id, + const std::wstring& contents, + const std::string& lang) { + NavigateAndCommit(url); + rvh()->TestOnMessageReceived(ViewHostMsg_PageContents(0, url, page_id, + contents, lang)); + } + + bool GetTranslateMessage(int* page_id, + std::string* original_lang, + std::string* target_lang) { + const IPC::Message* message = + process()->sink().GetFirstMessageMatching(ViewMsg_TranslatePage::ID); + if (!message) + return false; + Tuple3<int, 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; + return true; + } + + private: + TestTranslateManager translate_manager_; +}; + +TEST_F(TranslateManagerTest, NormalTranslate) { + // Simulate navigating to a page. + SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr"); + + // We should have an info-bar. + ASSERT_EQ(1, contents()->infobar_delegate_count()); + TranslateInfoBarDelegate* infobar = + contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate(); + ASSERT_TRUE(infobar != NULL); + EXPECT_EQ(TranslateInfoBarDelegate::kBeforeTranslate, infobar->state()); + + // Simulate clicking translate. + process()->sink().ClearMessages(); + infobar->Translate(); + + // Test that we sent the right message to the renderer. + int page_id = 0; + std::string original_lang, target_lang; + EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); + EXPECT_EQ(0, page_id); + EXPECT_EQ("fr", original_lang); + EXPECT_EQ("en", target_lang); + + // The infobar should now be in the translating state. + ASSERT_EQ(1, contents()->infobar_delegate_count()); + ASSERT_EQ(infobar, contents()->GetInfoBarDelegateAt(0)); // Same instance. + // TODO(jcampan): the state is not set if the button is not clicked. + // Refactor the infobar code so we can simulate the click. + // EXPECT_EQ(TranslateInfoBarDelegate::kTranslating, infobar->state()); + + // Simulate the render notifying the translation has been done. + rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en")); + + // The infobar should have changed to the after state. + ASSERT_EQ(1, contents()->infobar_delegate_count()); + ASSERT_EQ(infobar, contents()->GetInfoBarDelegateAt(0)); + // TODO(jcampan): the TranslateInfoBar is listening for the PAGE_TRANSLATED + // notification. Since in unit-test, no actual info-bar is + // created, it does not get the notification and does not + // update its state. Ideally the delegate (or rather model) + // would be the one listening for notifications and updating + // states. That would make this test work. + // EXPECT_EQ(TranslateInfoBarDelegate::kAfterTranslate, infobar->state()); + + // Simulate translating again from there but 2 different languages. + infobar->ModifyOriginalLanguage(0); + infobar->ModifyTargetLanguage(1); + std::string new_original_lang = infobar->original_lang_code(); + std::string new_target_lang = infobar->target_lang_code(); + process()->sink().ClearMessages(); + infobar->Translate(); + + // Test that we sent the right message to the renderer. + EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); + EXPECT_EQ(0, page_id); + EXPECT_EQ(new_original_lang, original_lang); + EXPECT_EQ(new_target_lang, target_lang); +} + +// Test auto-translate on page. +TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) { + // Simulate navigating to a page and gettings its language. + SimulateNavigation(GURL("http://www.google.fr"), 0, L"Le Google", "fr"); + + // Simulate the user translating. + ASSERT_EQ(1, contents()->infobar_delegate_count()); + TranslateInfoBarDelegate* infobar = + contents()->GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate(); + ASSERT_TRUE(infobar != NULL); + infobar->Translate(); + rvh()->TestOnMessageReceived(ViewHostMsg_PageTranslated(0, 0, "fr", "en")); + + // Now navigate to a new page in the same language. + process()->sink().ClearMessages(); + SimulateNavigation(GURL("http://news.google.fr"), 1, L"Les news", "fr"); + + // This should have automatically triggered a translation. + int page_id = 0; + std::string original_lang, target_lang; + EXPECT_TRUE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); + EXPECT_EQ(1, page_id); + EXPECT_EQ("fr", original_lang); + EXPECT_EQ("en", target_lang); + + // Now navigate to a page in a different language. + process()->sink().ClearMessages(); + SimulateNavigation(GURL("http://news.google.es"), 1, L"Las news", "es"); + + // This should not have triggered a translate. + EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); +} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index f9a7af1..567ecc5 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1731,6 +1731,8 @@ 'browser/tab_contents/infobar_delegate.h', 'browser/tab_contents/interstitial_page.cc', 'browser/tab_contents/interstitial_page.h', + 'browser/tab_contents/language_state.h', + 'browser/tab_contents/language_state.cc', 'browser/tab_contents/navigation_controller.cc', 'browser/tab_contents/navigation_controller.h', 'browser/tab_contents/navigation_entry.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index f1c9740..9855d8c 100755 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -826,6 +826,7 @@ 'browser/tab_menu_model_unittest.cc', 'browser/tabs/tab_strip_model_unittest.cc', 'browser/task_manager_unittest.cc', + 'browser/translate/translate_manager_unittest.cc', 'browser/theme_resources_util_unittest.cc', 'browser/views/bookmark_context_menu_test.cc', 'browser/views/bookmark_editor_view_unittest.cc', |