summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc5
-rw-r--r--chrome/browser/renderer_host/render_view_host.h3
-rw-r--r--chrome/browser/renderer_host/render_view_host_delegate.h3
-rw-r--r--chrome/browser/tab_contents/language_state.cc5
-rw-r--r--chrome/browser/tab_contents/language_state.h12
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc1
-rw-r--r--chrome/browser/tab_contents/tab_contents.cc5
-rw-r--r--chrome/browser/tab_contents/tab_contents.h3
-rw-r--r--chrome/browser/translate/translate_manager.cc3
-rw-r--r--chrome/browser/translate/translate_manager_unittest.cc141
-rw-r--r--chrome/common/render_messages_internal.h5
-rw-r--r--chrome/renderer/render_view.cc21
-rw-r--r--chrome/renderer/render_view.h6
-rw-r--r--webkit/glue/dom_operations.cc25
-rw-r--r--webkit/glue/dom_operations.h6
15 files changed, 178 insertions, 66 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index e7ba21f..cf890e4 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -1893,13 +1893,14 @@ void RenderViewHost::OnCSSInserted() {
void RenderViewHost::OnPageContents(const GURL& url,
int32 page_id,
const string16& contents,
- const std::string& language) {
+ const std::string& language,
+ bool page_translatable) {
RenderViewHostDelegate::BrowserIntegration* integration_delegate =
delegate_->GetBrowserIntegrationDelegate();
if (!integration_delegate)
return;
integration_delegate->OnPageContents(url, process()->id(), page_id, contents,
- language);
+ language, page_translatable);
}
void RenderViewHost::OnPageTranslated(int32 page_id,
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index e1073ec..aa66275 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -631,7 +631,8 @@ class RenderViewHost : public RenderWidgetHost {
void OnPageContents(const GURL& url,
int32 page_id,
const string16& contents,
- const std::string& language);
+ const std::string& language,
+ bool page_translatable);
void OnPageTranslated(int32 page_id,
const std::string& original_lang,
const std::string& translated_lang,
diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h
index a5fca32..eb2a555 100644
--- a/chrome/browser/renderer_host/render_view_host_delegate.h
+++ b/chrome/browser/renderer_host/render_view_host_delegate.h
@@ -243,7 +243,8 @@ class RenderViewHostDelegate {
int renderer_process_id,
int32 page_id,
const string16& contents,
- const std::string& language) = 0;
+ const std::string& language,
+ bool page_translatable) = 0;
// Notification that the page has been translated.
virtual void OnPageTranslated(int32 page_id,
diff --git a/chrome/browser/tab_contents/language_state.cc b/chrome/browser/tab_contents/language_state.cc
index d294eec..2808b2a 100644
--- a/chrome/browser/tab_contents/language_state.cc
+++ b/chrome/browser/tab_contents/language_state.cc
@@ -9,6 +9,7 @@
LanguageState::LanguageState(NavigationController* nav_controller)
: navigation_controller_(nav_controller),
+ page_translatable_(false),
translation_pending_(false),
translation_declined_(false),
in_page_navigation_(false) {
@@ -38,13 +39,15 @@ void LanguageState::DidNavigate(bool reload, bool in_page) {
translation_declined_ = false;
}
-void LanguageState::LanguageDetermined(const std::string& page_language) {
+void LanguageState::LanguageDetermined(const std::string& page_language,
+ bool page_translatable) {
if (in_page_navigation_ && !original_lang_.empty()) {
// In-page navigation, we don't expect our states to change.
// Note that we'll set the languages if original_lang_ is empty. This might
// happen if the we did not get called on the top-page.
return;
}
+ page_translatable_ = page_translatable;
original_lang_ = page_language;
current_lang_ = page_language;
}
diff --git a/chrome/browser/tab_contents/language_state.h b/chrome/browser/tab_contents/language_state.h
index f428229..8cbdfd7 100644
--- a/chrome/browser/tab_contents/language_state.h
+++ b/chrome/browser/tab_contents/language_state.h
@@ -30,7 +30,10 @@ class LanguageState {
void DidNavigate(bool reload, bool in_page_navigation);
// Should be called when the language of the page has been determined.
- void LanguageDetermined(const std::string& page_language);
+ // |page_translatable| when false indicates that the browser should not offer
+ // to translate the page.
+ void LanguageDetermined(const std::string& page_language,
+ bool page_translatable);
// Returns the language the current page should be translated to, based on the
// previous page languages and the transition. This should be called after
@@ -48,6 +51,8 @@ class LanguageState {
}
const std::string& current_language() const { return current_lang_; }
+ bool page_translatable() const { return page_translatable_; }
+
// 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; }
@@ -75,6 +80,11 @@ class LanguageState {
// The navigation controller of the tab we are associated with.
NavigationController* navigation_controller_;
+ // Whether it is OK to offer to translate the page. Some pages explictly
+ // specify that they should not be translated by the browser (this is the case
+ // for GMail for example, which provides its own translation features).
+ bool page_translatable_;
+
// 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
diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc
index c912965..f513891 100644
--- a/chrome/browser/tab_contents/render_view_context_menu.cc
+++ b/chrome/browser/tab_contents/render_view_context_menu.cc
@@ -730,6 +730,7 @@ bool RenderViewContextMenu::IsCommandIdEnabled(int id) const {
std::string target_lang = g_browser_process->GetApplicationLocale();
target_lang = TranslateManager::GetLanguageCode(target_lang);
return !!(params_.edit_flags & WebContextMenuData::CanTranslate) &&
+ source_tab_contents_->language_state().page_translatable() &&
original_lang != target_lang &&
!source_tab_contents_->language_state().IsPageTranslated() &&
!source_tab_contents_->interstitial_page() &&
diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc
index 8a29653..5457a0d 100644
--- a/chrome/browser/tab_contents/tab_contents.cc
+++ b/chrome/browser/tab_contents/tab_contents.cc
@@ -1959,7 +1959,8 @@ void TabContents::OnPageContents(const GURL& url,
int renderer_process_id,
int32 page_id,
const string16& contents,
- const std::string& language) {
+ const std::string& language,
+ bool page_translatable) {
// Don't index any https pages. People generally don't want their bank
// accounts, etc. indexed on their computer, especially since some of these
// things are not marked cachable.
@@ -1979,7 +1980,7 @@ void TabContents::OnPageContents(const GURL& url,
}
#endif
- language_state_.LanguageDetermined(language);
+ language_state_.LanguageDetermined(language, page_translatable);
std::string lang = language;
NotificationService::current()->Notify(
diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h
index a96a790..304a6d2 100644
--- a/chrome/browser/tab_contents/tab_contents.h
+++ b/chrome/browser/tab_contents/tab_contents.h
@@ -843,7 +843,8 @@ class TabContents : public PageNavigator,
int renderer_process_id,
int32 page_id,
const string16& contents,
- const std::string& language);
+ const std::string& language,
+ bool page_translatable);
virtual void OnPageTranslated(int32 page_id,
const std::string& original_lang,
const std::string& translated_lang,
diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc
index 2a02546..073f0c0 100644
--- a/chrome/browser/translate/translate_manager.cc
+++ b/chrome/browser/translate/translate_manager.cc
@@ -197,7 +197,8 @@ void TranslateManager::Observe(NotificationType type,
// We may get this notifications multiple times. Make sure to translate
// only once.
LanguageState& language_state = tab->language_state();
- if (!language_state.translation_pending() &&
+ if (language_state.page_translatable() &&
+ !language_state.translation_pending() &&
!language_state.translation_declined() &&
!language_state.IsPageTranslated()) {
std::string language = *(Details<std::string>(details).ptr());
diff --git a/chrome/browser/translate/translate_manager_unittest.cc b/chrome/browser/translate/translate_manager_unittest.cc
index 79e3962a..88710a9 100644
--- a/chrome/browser/translate/translate_manager_unittest.cc
+++ b/chrome/browser/translate/translate_manager_unittest.cc
@@ -45,17 +45,20 @@ class TranslateManagerTest : public RenderViewHostTestHarness,
// for that navigation.
void SimulateNavigation(const GURL& url, int page_id,
const std::string& contents,
- const std::string& lang) {
+ const std::string& lang,
+ bool page_translatable) {
NavigateAndCommit(url);
- SimulateOnPageContents(url, page_id, contents, lang);
+ SimulateOnPageContents(url, page_id, contents, lang, page_translatable);
}
void SimulateOnPageContents(const GURL& url, int page_id,
const std::string& contents,
- const std::string& lang) {
+ const std::string& lang,
+ bool page_translatable) {
rvh()->TestOnMessageReceived(ViewHostMsg_PageContents(0, url, page_id,
UTF8ToUTF16(contents),
- lang));
+ lang,
+ page_translatable));
}
bool GetTranslateMessage(int* page_id,
@@ -270,7 +273,7 @@ class TestRenderViewContextMenu : public RenderViewContextMenu {
TEST_F(TranslateManagerTest, NormalTranslate) {
// Simulate navigating to a page.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// We should have an infobar.
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
@@ -341,7 +344,7 @@ TEST_F(TranslateManagerTest, NormalTranslate) {
TEST_F(TranslateManagerTest, TranslateScriptNotAvailable) {
// Simulate navigating to a page.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// We should have an infobar.
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
@@ -368,7 +371,7 @@ TEST_F(TranslateManagerTest, TranslateScriptNotAvailable) {
TEST_F(TranslateManagerTest, TranslateUnknownLanguage) {
// Simulate navigating to a page ("und" is the string returned by the CLD for
// languages it does not recognize).
- SimulateNavigation(GURL("http://www.google.mys"), 0, "G00g1e", "und");
+ SimulateNavigation(GURL("http://www.google.mys"), 0, "G00g1e", "und", true);
// We should not have an infobar as we don't know the language.
ASSERT_TRUE(GetTranslateInfoBar() == NULL);
@@ -394,7 +397,8 @@ TEST_F(TranslateManagerTest, TranslateUnknownLanguage) {
// Let's run the same steps but this time the server detects the page is
// already in English.
- SimulateNavigation(GURL("http://www.google.com"), 1, "The Google", "und");
+ SimulateNavigation(GURL("http://www.google.com"), 1, "The Google", "und",
+ true);
menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents()));
menu->Init();
menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
@@ -407,7 +411,8 @@ TEST_F(TranslateManagerTest, TranslateUnknownLanguage) {
// Let's run the same steps again but this time the server fails to detect the
// page's language (it returns an empty string).
- SimulateNavigation(GURL("http://www.google.com"), 2, "The Google", "und");
+ SimulateNavigation(GURL("http://www.google.com"), 2, "The Google", "und",
+ true);
menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents()));
menu->Init();
menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE);
@@ -477,7 +482,7 @@ TEST_F(TranslateManagerTest, TestAllLanguages) {
// Simulate navigating to a page.
NavigateAndCommit(url);
- SimulateOnPageContents(url, i, "", lang);
+ SimulateOnPageContents(url, i, "", lang, true);
// Verify we have/don't have an info-bar as expected.
infobar = GetTranslateInfoBar();
@@ -492,7 +497,7 @@ TEST_F(TranslateManagerTest, TestAllLanguages) {
// Tests auto-translate on page.
TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) {
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// Simulate the user translating.
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
@@ -505,7 +510,7 @@ TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) {
// Now navigate to a new page in the same language.
process()->sink().ClearMessages();
- SimulateNavigation(GURL("http://news.google.fr"), 1, "Les news", "fr");
+ SimulateNavigation(GURL("http://news.google.fr"), 1, "Les news", "fr", true);
// This should have automatically triggered a translation.
int page_id = 0;
@@ -517,7 +522,7 @@ TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) {
// Now navigate to a page in a different language.
process()->sink().ClearMessages();
- SimulateNavigation(GURL("http://news.google.es"), 1, "Las news", "es");
+ SimulateNavigation(GURL("http://news.google.es"), 1, "Las news", "es", true);
// This should not have triggered a translate.
EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
@@ -526,28 +531,31 @@ TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) {
// Tests that multiple OnPageContents do not cause multiple infobars.
TEST_F(TranslateManagerTest, MultipleOnPageContents) {
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// Simulate clicking 'Nope' (don't translate).
EXPECT_TRUE(DenyTranslation());
EXPECT_EQ(0, contents()->infobar_delegate_count());
// Send a new PageContents, we should not show an infobar.
- SimulateOnPageContents(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateOnPageContents(GURL("http://www.google.fr"), 0, "Le Google", "fr",
+ true);
EXPECT_EQ(0, contents()->infobar_delegate_count());
// Do the same steps but simulate closing the infobar this time.
- SimulateNavigation(GURL("http://www.youtube.fr"), 1, "Le YouTube", "fr");
+ SimulateNavigation(GURL("http://www.youtube.fr"), 1, "Le YouTube", "fr",
+ true);
EXPECT_TRUE(CloseTranslateInfoBar());
EXPECT_EQ(0, contents()->infobar_delegate_count());
- SimulateOnPageContents(GURL("http://www.youtube.fr"), 1, "Le YouTube", "fr");
+ SimulateOnPageContents(GURL("http://www.youtube.fr"), 1, "Le YouTube", "fr",
+ true);
EXPECT_EQ(0, contents()->infobar_delegate_count());
}
// Test that reloading the page brings back the infobar.
TEST_F(TranslateManagerTest, Reload) {
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// Close the infobar.
EXPECT_TRUE(CloseTranslateInfoBar());
@@ -574,7 +582,7 @@ TEST_F(TranslateManagerTest, ReloadFromLocationBar) {
GURL url("http://www.google.fr");
// Simulate navigating to a page and getting its language.
- SimulateNavigation(url, 0, "Le Google", "fr");
+ SimulateNavigation(url, 0, "Le Google", "fr", true);
// Close the infobar.
EXPECT_TRUE(CloseTranslateInfoBar());
@@ -602,34 +610,38 @@ TEST_F(TranslateManagerTest, ReloadFromLocationBar) {
// in-page.
TEST_F(TranslateManagerTest, CloseInfoBarInPageNavigation) {
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// Close the infobar.
EXPECT_TRUE(CloseTranslateInfoBar());
// Navigate in page, no infobar should be shown.
- SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr",
+ true);
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
// Navigate out of page, a new infobar should show.
- SimulateNavigation(GURL("http://www.google.fr/foot"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr/foot"), 0, "Le Google", "fr",
+ true);
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
}
// Tests that denying translation is sticky when navigating in page.
TEST_F(TranslateManagerTest, DenyTranslateInPageNavigation) {
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// Simulate clicking 'Nope' (don't translate).
EXPECT_TRUE(DenyTranslation());
// Navigate in page, no infobar should be shown.
- SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr",
+ true);
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
// Navigate out of page, a new infobar should show.
- SimulateNavigation(GURL("http://www.google.fr/foot"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr/foot"), 0, "Le Google", "fr",
+ true);
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
}
@@ -637,7 +649,7 @@ TEST_F(TranslateManagerTest, DenyTranslateInPageNavigation) {
// return when navigating in page.
TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) {
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// Simulate the user translating.
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
@@ -651,14 +663,15 @@ TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) {
EXPECT_TRUE(CloseTranslateInfoBar());
// Navigate in page, no infobar should be shown.
- SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr",
+ true);
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
// Navigate out of page, a new infobar should show.
// Note that we navigate to a page in a different language so we don't trigger
// the auto-translate feature (it would translate the page automatically and
// the before translate inforbar would not be shown).
- SimulateNavigation(GURL("http://www.google.de"), 0, "Das Google", "de");
+ SimulateNavigation(GURL("http://www.google.de"), 0, "Das Google", "de", true);
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
}
@@ -666,7 +679,7 @@ TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) {
// in-page.
TEST_F(TranslateManagerTest, TranslateInPageNavigation) {
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// Simulate the user translating.
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
@@ -681,14 +694,15 @@ TEST_F(TranslateManagerTest, TranslateInPageNavigation) {
// Navigate in page, the same infobar should still be shown.
ClearRemovedInfoBars();
- SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr/#ref1"), 0, "Le Google", "fr",
+ true);
EXPECT_FALSE(InfoBarRemoved());
EXPECT_EQ(infobar, GetTranslateInfoBar());
// Navigate out of page, a new infobar should show.
// See note in TranslateCloseInfoBarInPageNavigation test on why it is
// important to navigate to a page in a different language for this test.
- SimulateNavigation(GURL("http://www.google.de"), 0, "Das Google", "de");
+ SimulateNavigation(GURL("http://www.google.de"), 0, "Das Google", "de", true);
// The old infobar is gone.
EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar));
// And there is a new one.
@@ -699,7 +713,7 @@ TEST_F(TranslateManagerTest, TranslateInPageNavigation) {
// unsupported language.
TEST_F(TranslateManagerTest, UnsupportedPageLanguage) {
// Simulate navigating to a page and getting an unsupported language.
- SimulateNavigation(GURL("http://www.google.com"), 0, "Google", "qbz");
+ SimulateNavigation(GURL("http://www.google.com"), 0, "Google", "qbz", true);
// No info-bar should be shown.
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
@@ -715,7 +729,7 @@ TEST_F(TranslateManagerTest, UnsupportedUILanguage) {
// Simulate navigating to a page in a language supported by the translate
// server.
- SimulateNavigation(GURL("http://www.google.com"), 0, "Google", "en");
+ SimulateNavigation(GURL("http://www.google.com"), 0, "Google", "en", true);
// No info-bar should be shown.
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
@@ -730,7 +744,7 @@ TEST_F(TranslateManagerTest, TranslateEnabledPref) {
prefs->SetBoolean(prefs::kEnableTranslate, true);
// Simulate navigating to a page and getting its language.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// An infobar should be shown.
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
@@ -747,7 +761,7 @@ TEST_F(TranslateManagerTest, TranslateEnabledPref) {
// Simulate getting the page contents and language, that should not trigger
// a translate infobar.
- SimulateOnPageContents(url, 1, "Le YouTube", "fr");
+ SimulateOnPageContents(url, 1, "Le YouTube", "fr", true);
infobar = GetTranslateInfoBar();
EXPECT_TRUE(infobar == NULL);
}
@@ -756,7 +770,7 @@ TEST_F(TranslateManagerTest, TranslateEnabledPref) {
TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) {
// Simulate navigating to a page and getting its language.
GURL url("http://www.google.fr");
- SimulateNavigation(url, 0, "Le Google", "fr");
+ SimulateNavigation(url, 0, "Le Google", "fr", true);
// An infobar should be shown.
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
@@ -777,7 +791,8 @@ TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) {
EXPECT_TRUE(CloseTranslateInfoBar());
// Navigate to a new page also in French.
- SimulateNavigation(GURL("http://wwww.youtube.fr"), 1, "Le YouTube", "fr");
+ SimulateNavigation(GURL("http://wwww.youtube.fr"), 1, "Le YouTube", "fr",
+ true);
// There should not be a translate infobar.
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
@@ -789,7 +804,7 @@ TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) {
EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
// Navigate to a page in French.
- SimulateNavigation(url, 2, "Le Google", "fr");
+ SimulateNavigation(url, 2, "Le Google", "fr", true);
// There should be a translate infobar.
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
@@ -802,7 +817,7 @@ TEST_F(TranslateManagerTest, NeverTranslateSitePref) {
// Simulate navigating to a page and getting its language.
GURL url("http://www.google.fr");
std::string host(url.host());
- SimulateNavigation(url, 0, "Le Google", "fr");
+ SimulateNavigation(url, 0, "Le Google", "fr", true);
// An infobar should be shown.
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
@@ -823,7 +838,8 @@ TEST_F(TranslateManagerTest, NeverTranslateSitePref) {
EXPECT_TRUE(CloseTranslateInfoBar());
// Navigate to a new page also on the same site.
- SimulateNavigation(GURL("http://www.google.fr/hello"), 1, "Bonjour", "fr");
+ SimulateNavigation(GURL("http://www.google.fr/hello"), 1, "Bonjour", "fr",
+ true);
// There should not be a translate infobar.
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
@@ -835,7 +851,7 @@ TEST_F(TranslateManagerTest, NeverTranslateSitePref) {
EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url));
// Navigate to a page in French.
- SimulateNavigation(url, 0, "Le Google", "fr");
+ SimulateNavigation(url, 0, "Le Google", "fr", true);
// There should be a translate infobar.
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
@@ -854,7 +870,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) {
translate_prefs.WhitelistLanguagePair("fr", "en");
// Load a page in French.
- SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 0, "Le Google", "fr", true);
// It should have triggered an automatic translation to English.
SimulateURLFetch(true); // Simulate the translate script being retrieved.
@@ -870,7 +886,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) {
EXPECT_TRUE(GetTranslateInfoBar() == NULL);
// Try another language, it should not be autotranslated.
- SimulateNavigation(GURL("http://www.google.es"), 1, "El Google", "es");
+ SimulateNavigation(GURL("http://www.google.es"), 1, "El Google", "es", true);
EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
EXPECT_TRUE(CloseTranslateInfoBar());
@@ -880,7 +896,8 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) {
TestingProfile* test_profile =
static_cast<TestingProfile*>(contents()->profile());
test_profile->set_off_the_record(true);
- SimulateNavigation(GURL("http://www.youtube.fr"), 2, "Le YouTube", "fr");
+ SimulateNavigation(GURL("http://www.youtube.fr"), 2, "Le YouTube", "fr",
+ true);
EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
EXPECT_TRUE(CloseTranslateInfoBar());
@@ -890,7 +907,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) {
// behavior, which is show an infobar.
SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists);
translate_prefs.RemoveLanguagePairFromWhitelist("fr", "en");
- SimulateNavigation(GURL("http://www.google.fr"), 3, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 3, "Le Google", "fr", true);
EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang));
EXPECT_TRUE(GetTranslateInfoBar() != NULL);
prefs->RemovePrefObserver(TranslatePrefs::kPrefTranslateWhitelists,
@@ -908,7 +925,7 @@ TEST_F(TranslateManagerTest, ContextMenu) {
EXPECT_TRUE(translate_prefs.IsSiteBlacklisted(url.host()));
// Simulate navigating to a page in French. The translate menu should show.
- SimulateNavigation(url, 0, "Le Google", "fr");
+ SimulateNavigation(url, 0, "Le Google", "fr", true);
scoped_ptr<TestRenderViewContextMenu> menu(
TestRenderViewContextMenu::CreateContextMenu(contents()));
menu->Init();
@@ -945,7 +962,7 @@ TEST_F(TranslateManagerTest, ContextMenu) {
// Test that selecting translate in the context menu WHILE the page is being
// translated does nothing (this could happen if autotranslate kicks-in and
// the user selects the menu while the translation is being performed).
- SimulateNavigation(GURL("http://www.google.es"), 1, "El Google", "es");
+ SimulateNavigation(GURL("http://www.google.es"), 1, "El Google", "es", true);
TranslateInfoBarDelegate* infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
infobar->Translate();
@@ -961,7 +978,7 @@ TEST_F(TranslateManagerTest, ContextMenu) {
// Now test that selecting translate in the context menu AFTER the page has
// been translated does nothing.
- SimulateNavigation(GURL("http://www.google.de"), 2, "Das Google", "de");
+ SimulateNavigation(GURL("http://www.google.de"), 2, "Das Google", "de", true);
infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
infobar->Translate();
@@ -979,7 +996,7 @@ TEST_F(TranslateManagerTest, ContextMenu) {
// Test that the translate context menu is disabled when the page is in the
// same language as the UI.
- SimulateNavigation(url, 0, "Google", "en");
+ SimulateNavigation(url, 0, "Google", "en", true);
menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents()));
menu->Init();
EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
@@ -987,7 +1004,7 @@ TEST_F(TranslateManagerTest, ContextMenu) {
// Test that the translate context menu is enabled when the page is in an
// unknown language as the UI.
- SimulateNavigation(url, 0, "G00g1e", "und");
+ SimulateNavigation(url, 0, "G00g1e", "und", true);
menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents()));
menu->Init();
EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
@@ -1005,7 +1022,8 @@ TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) {
TranslateInfoBarDelegate* infobar;
for (int i = 0; i < 4; ++i) {
- SimulateNavigation(GURL("http://www.google.fr"), 1, "Le Google", "fr");
+ SimulateNavigation(GURL("http://www.google.fr"), 1, "Le Google", "fr",
+ true);
infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
EXPECT_EQ(TranslateInfoBarDelegate::kBeforeTranslate, infobar->type());
@@ -1032,7 +1050,8 @@ TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) {
// Now test that declining the translation causes a "never translate" button
// to be shown.
for (int i = 0; i < 4; ++i) {
- SimulateNavigation(GURL("http://www.google.de"), 1, "Das Google", "de");
+ SimulateNavigation(GURL("http://www.google.de"), 1, "Das Google", "de",
+ true);
infobar = GetTranslateInfoBar();
ASSERT_TRUE(infobar != NULL);
EXPECT_EQ(TranslateInfoBarDelegate::kBeforeTranslate, infobar->type());
@@ -1051,3 +1070,21 @@ TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) {
process()->sink().ClearMessages();
ASSERT_TRUE(GetTranslateInfoBar() == NULL);
}
+
+// Tests that we don't show a translate infobar when a page instructs that it
+// should not be translated.
+TEST_F(TranslateManagerTest, NonTranslatablePage) {
+ // Simulate navigating to a page.
+ SimulateNavigation(GURL("http://mail.google.fr"), 0, "Le Google", "fr",
+ false);
+
+ // We should not have an infobar.
+ EXPECT_TRUE(GetTranslateInfoBar() == NULL);
+
+ // The context menu should be disabled.
+ scoped_ptr<TestRenderViewContextMenu> menu(
+ TestRenderViewContextMenu::CreateContextMenu(contents()));
+ menu->Init();
+ EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE));
+ EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE));
+}
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 0b8e903..5fc758f 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -1299,11 +1299,12 @@ IPC_BEGIN_MESSAGES(ViewHost)
std::wstring /* out - prompt field */)
// Provides the contents for the given page that was loaded recently.
- IPC_MESSAGE_ROUTED4(ViewHostMsg_PageContents,
+ IPC_MESSAGE_ROUTED5(ViewHostMsg_PageContents,
GURL /* URL of the page */,
int32 /* page id */,
string16 /* page contents */,
- std::string /* page ISO639_1 language code */)
+ std::string /* page ISO639_1 language code */,
+ bool /* whether the page can be translated */)
// Used to get the extension message bundle.
IPC_SYNC_MESSAGE_CONTROL1_1(ViewHostMsg_GetExtensionMessageBundle,
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 1386917..7030f80 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -838,11 +838,11 @@ void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) {
std::string language = DetermineTextLanguage(contents);
UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.LanguageDetection",
base::TimeTicks::Now() - begin_time);
-
+ WebKit::WebDocument document = main_frame->document();
// Send the text to the browser for indexing (the browser might decide not
// to index, if the URL is HTTPS for instance) and language discovery.
Send(new ViewHostMsg_PageContents(routing_id_, url, load_id, contents,
- language));
+ language, IsPageTranslatable(&document)));
}
OnCaptureThumbnail();
@@ -1978,6 +1978,23 @@ void RenderView::UpdateTargetURL(const GURL& url, const GURL& fallback_url) {
}
}
+bool RenderView::IsPageTranslatable(WebKit::WebDocument* document) {
+ std::vector<WebKit::WebElement> meta_elements;
+ webkit_glue::GetMetaElementsWithName(document, ASCIIToUTF16("google"),
+ &meta_elements);
+ std::vector<WebKit::WebElement>::const_iterator iter;
+ for (iter = meta_elements.begin(); iter != meta_elements.end(); ++iter) {
+ WebString attribute = iter->getAttribute("value");
+ if (attribute.isNull()) // We support both 'value' and 'content'.
+ attribute = iter->getAttribute("content");
+ if (attribute.isNull())
+ continue;
+ if (LowerCaseEqualsASCII(attribute, "notranslate"))
+ return false;
+ }
+ return true;
+}
+
void RenderView::StartNavStateSyncTimerIfNecessary() {
int delay;
if (send_content_state_immediately_)
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index ea515b4..71b8693 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -103,6 +103,7 @@ class WebAccessibilityCache;
class WebApplicationCacheHost;
class WebApplicationCacheHostClient;
class WebDataSource;
+class WebDocument;
class WebDragData;
class WebGeolocationServiceInterface;
class WebImage;
@@ -933,6 +934,11 @@ class RenderView : public RenderWidget,
// If |only_visible| is true, only forms visible in the layout are sent
void SendPasswordForms(WebKit::WebFrame* frame, bool only_visible);
+ // Returns whether the page associated with |document| is a candidate for
+ // translation. Some pages can explictly specify (via a meta-tag) that they
+ // should not be translated.
+ bool IsPageTranslatable(WebKit::WebDocument* document);
+
// Starts nav_state_sync_timer_ if it isn't already running.
void StartNavStateSyncTimerIfNecessary();
diff --git a/webkit/glue/dom_operations.cc b/webkit/glue/dom_operations.cc
index d0b371d..017c3c6 100644
--- a/webkit/glue/dom_operations.cc
+++ b/webkit/glue/dom_operations.cc
@@ -590,4 +590,29 @@ int NumberOfActiveAnimations(WebView* view) {
return controller->numberOfActiveAnimations();
}
+void GetMetaElementsWithName(WebDocument* document,
+ const string16& name,
+ std::vector<WebElement>* meta_elements) {
+ DCHECK(document);
+ DCHECK(meta_elements);
+ meta_elements->clear();
+ WebElement head = document->head();
+ if (head.isNull() || !head.hasChildNodes())
+ return;
+
+ WebNodeList children = head.childNodes();
+ for (size_t i = 0; i < children.length(); ++i) {
+ WebNode node = children.item(i);
+ if (!node.isElementNode())
+ continue;
+ WebElement element = node.to<WebElement>();
+ if (!element.hasTagName("meta"))
+ continue;
+ WebString meta_name = element.getAttribute("name");
+ if (meta_name.isNull() || meta_name != name)
+ continue;
+ meta_elements->push_back(element);
+ }
+}
+
} // webkit_glue
diff --git a/webkit/glue/dom_operations.h b/webkit/glue/dom_operations.h
index 4741bce..b8915be 100644
--- a/webkit/glue/dom_operations.h
+++ b/webkit/glue/dom_operations.h
@@ -129,6 +129,12 @@ int NumberOfActiveAnimations(WebKit::WebView* view);
WebKit::WebString GetSubResourceLinkFromElement(
const WebKit::WebElement& element);
+// Puts the meta-elements of |document| that have the specified |name| in
+// |meta_elements|.
+void GetMetaElementsWithName(WebKit::WebDocument* document,
+ const string16& name,
+ std::vector<WebKit::WebElement>* meta_elements);
+
} // namespace webkit_glue
#endif // WEBKIT_GLUE_DOM_OPERATIONS_H__