diff options
40 files changed, 880 insertions, 661 deletions
diff --git a/chrome/browser/autofill/autofill_browsertest.cc b/chrome/browser/autofill/autofill_browsertest.cc index 2f85a61..7808db7 100644 --- a/chrome/browser/autofill/autofill_browsertest.cc +++ b/chrome/browser/autofill/autofill_browsertest.cc @@ -20,13 +20,13 @@ #include "chrome/browser/ui/browser_window.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/net/test_url_fetcher_factory.h" +#include "chrome/common/render_messages.h" #include "chrome/renderer/translate_helper.h" #include "chrome/test/in_process_browser_test.h" #include "chrome/test/ui_test_utils.h" #include "content/browser/renderer_host/mock_render_process_host.h" #include "content/browser/renderer_host/render_view_host.h" #include "content/browser/tab_contents/tab_contents.h" -#include "content/common/view_messages.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/base/keycodes/keyboard_codes.h" @@ -434,10 +434,8 @@ IN_PROC_BROWSER_TEST_F(AutofillTest, AutofillAfterTranslate) { ASSERT_NO_FATAL_FAILURE(ui_test_utils::NavigateToURL(browser(), url)); // Get translation bar. - int page_id = browser()->GetSelectedTabContents()->controller(). - GetLastCommittedEntry()->page_id(); - render_view_host()->OnMessageReceived(ViewHostMsg_PageContents( - 0, url, page_id, ASCIIToUTF16("test"), "ja", true)); + render_view_host()->OnMessageReceived(ViewHostMsg_TranslateLanguageDetermined( + 0, "ja", true)); TranslateInfoBarDelegate* infobar = browser()->GetSelectedTabContents()-> GetInfoBarDelegateAt(0)->AsTranslateInfoBarDelegate(); diff --git a/chrome/browser/automation/automation_provider_observers.cc b/chrome/browser/automation/automation_provider_observers.cc index ba64791..c4986f1 100644 --- a/chrome/browser/automation/automation_provider_observers.cc +++ b/chrome/browser/automation/automation_provider_observers.cc @@ -44,6 +44,7 @@ #include "chrome/browser/tab_contents/thumbnail_generator.h" #include "chrome/browser/translate/page_translated_details.h" #include "chrome/browser/translate/translate_infobar_delegate.h" +#include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/find_bar/find_notification_details.h" @@ -1303,17 +1304,18 @@ void TabLanguageDeterminedObserver::Observe( return; } + TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents( + tab_contents_)->translate_tab_helper(); scoped_ptr<DictionaryValue> return_value(new DictionaryValue); return_value->SetBoolean("page_translated", - tab_contents_->language_state().IsPageTranslated()); + helper->language_state().IsPageTranslated()); return_value->SetBoolean( "can_translate_page", TranslatePrefs::CanTranslate( automation_->profile()->GetPrefs(), - tab_contents_->language_state().original_language(), + helper->language_state().original_language(), tab_contents_->GetURL())); - return_value->SetString( - "original_language", - tab_contents_->language_state().original_language()); + return_value->SetString("original_language", + helper->language_state().original_language()); if (translate_bar_) { DictionaryValue* bar_info = new DictionaryValue; std::map<TranslateInfoBarDelegate::Type, std::string> type_to_string; diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 8c8943f..a2d9055 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -67,6 +67,7 @@ #include "chrome/browser/themes/theme_service.h" #include "chrome/browser/themes/theme_service_factory.h" #include "chrome/browser/translate/translate_infobar_delegate.h" +#include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h" #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" @@ -3634,7 +3635,9 @@ void TestingAutomationProvider::GetTranslateInfo( this, reply_message, tab_contents, translate_bar); // If the language for the page hasn't been loaded yet, then just make // the observer, otherwise call observe directly. - std::string language = tab_contents->language_state().original_language(); + TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents( + tab_contents)->translate_tab_helper(); + std::string language = helper->language_state().original_language(); if (!language.empty()) { observer->Observe(NotificationType::TAB_LANGUAGE_DETERMINED, Source<TabContents>(tab_contents), diff --git a/chrome/browser/browser_browsertest.cc b/chrome/browser/browser_browsertest.cc index 71746e5..8fb1a53 100644 --- a/chrome/browser/browser_browsertest.cc +++ b/chrome/browser/browser_browsertest.cc @@ -16,6 +16,7 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tabs/pinned_tab_codec.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" #include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h" #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" @@ -560,6 +561,8 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_PageLanguageDetection) { ASSERT_TRUE(test_server()->Start()); TabContents* current_tab = browser()->GetSelectedTabContents(); + TabContentsWrapper* wrapper = browser()->GetSelectedTabContentsWrapper(); + TranslateTabHelper* helper = wrapper->translate_tab_helper(); Source<TabContents> source(current_tab); // Navigate to a page in English. @@ -568,13 +571,13 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_PageLanguageDetection) { source); ui_test_utils::NavigateToURL( browser(), GURL(test_server()->GetURL("files/english_page.html"))); - EXPECT_TRUE(current_tab->language_state().original_language().empty()); + EXPECT_TRUE(helper->language_state().original_language().empty()); en_language_detected_signal.Wait(); std::string lang; EXPECT_TRUE(en_language_detected_signal.GetDetailsFor( source.map_key(), &lang)); EXPECT_EQ("en", lang); - EXPECT_EQ("en", current_tab->language_state().original_language()); + EXPECT_EQ("en", helper->language_state().original_language()); // Now navigate to a page in French. ui_test_utils::WindowedNotificationObserverWithDetails<std::string> @@ -582,13 +585,13 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_PageLanguageDetection) { source); ui_test_utils::NavigateToURL( browser(), GURL(test_server()->GetURL("files/french_page.html"))); - EXPECT_TRUE(current_tab->language_state().original_language().empty()); + EXPECT_TRUE(helper->language_state().original_language().empty()); fr_language_detected_signal.Wait(); lang.clear(); EXPECT_TRUE(fr_language_detected_signal.GetDetailsFor( source.map_key(), &lang)); EXPECT_EQ("fr", lang); - EXPECT_EQ("fr", current_tab->language_state().original_language()); + EXPECT_EQ("fr", helper->language_state().original_language()); } // Chromeos defaults to restoring the last session, so this test isn't diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index 3ea3607..e986d91 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -18,6 +18,7 @@ #include "chrome/browser/extensions/extension_tabs_module_constants.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tabs/tab_strip_model.h" +#include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" #include "chrome/browser/ui/browser_navigator.h" @@ -1262,12 +1263,13 @@ bool DetectTabLanguageFunction::RunImpl() { AddRef(); // Balanced in GotLanguage() - if (!contents->tab_contents()->language_state().original_language().empty()) { + TranslateTabHelper* helper = contents->translate_tab_helper(); + if (!helper->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->tab_contents()->language_state().original_language())); + helper->language_state().original_language())); return true; } // The tab contents does not know its language yet. Let's wait until it diff --git a/content/browser/tab_contents/language_state.cc b/chrome/browser/tab_contents/language_state.cc index 86712d1..baf1bdd 100644 --- a/content/browser/tab_contents/language_state.cc +++ b/chrome/browser/tab_contents/language_state.cc @@ -1,8 +1,8 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 "content/browser/tab_contents/language_state.h" +#include "chrome/browser/tab_contents/language_state.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/navigation_entry.h" diff --git a/content/browser/tab_contents/language_state.h b/chrome/browser/tab_contents/language_state.h index d0c6204..b9f4d33 100644 --- a/content/browser/tab_contents/language_state.h +++ b/chrome/browser/tab_contents/language_state.h @@ -1,9 +1,9 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 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 CONTENT_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ -#define CONTENT_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ +#ifndef CHROME_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ +#define CHROME_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ #pragma once #include <string> @@ -106,4 +106,4 @@ class LanguageState { DISALLOW_COPY_AND_ASSIGN(LanguageState); }; -#endif // CONTENT_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ +#endif // CHROME_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ diff --git a/chrome/browser/tab_contents/render_view_context_menu.cc b/chrome/browser/tab_contents/render_view_context_menu.cc index ba1af43..ae99479 100644 --- a/chrome/browser/tab_contents/render_view_context_menu.cc +++ b/chrome/browser/tab_contents/render_view_context_menu.cc @@ -39,6 +39,7 @@ #include "chrome/browser/spellchecker_platform_engine.h" #include "chrome/browser/translate/translate_manager.h" #include "chrome/browser/translate/translate_prefs.h" +#include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/download/download_tab_helper.h" #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/chrome_constants.h" @@ -902,8 +903,11 @@ bool RenderViewContextMenu::IsCommandIdEnabled(int id) const { return IsDevCommandEnabled(id); case IDC_CONTENT_CONTEXT_TRANSLATE: { + TranslateTabHelper* helper = + TabContentsWrapper::GetCurrentWrapperForContents( + source_tab_contents_)->translate_tab_helper(); std::string original_lang = - source_tab_contents_->language_state().original_language(); + helper->language_state().original_language(); std::string target_lang = g_browser_process->GetApplicationLocale(); target_lang = TranslateManager::GetLanguageCode(target_lang); // Note that we intentionally enable the menu even if the original and @@ -911,14 +915,14 @@ bool RenderViewContextMenu::IsCommandIdEnabled(int id) const { // translate a page that might contains text fragments in a different // language. return !!(params_.edit_flags & WebContextMenuData::CanTranslate) && - source_tab_contents_->language_state().page_translatable() && + helper->language_state().page_translatable() && !original_lang.empty() && // Did we receive the page language yet? // Only allow translating languages we explitly support and the // unknown language (in which case the page language is detected on // the server side). (original_lang == chrome::kUnknownLanguageCode || TranslateManager::IsSupportedLanguage(original_lang)) && - !source_tab_contents_->language_state().IsPageTranslated() && + !helper->language_state().IsPageTranslated() && !source_tab_contents_->interstitial_page() && TranslateManager::IsTranslatableURL(params_.page_url); } @@ -1339,12 +1343,14 @@ void RenderViewContextMenu::ExecuteCommand(int id) { case IDC_CONTENT_CONTEXT_TRANSLATE: { // A translation might have been triggered by the time the menu got // selected, do nothing in that case. - if (source_tab_contents_->language_state().IsPageTranslated() || - source_tab_contents_->language_state().translation_pending()) { + TranslateTabHelper* helper = + TabContentsWrapper::GetCurrentWrapperForContents( + source_tab_contents_)->translate_tab_helper(); + if (helper->language_state().IsPageTranslated() || + helper->language_state().translation_pending()) { return; } - std::string original_lang = - source_tab_contents_->language_state().original_language(); + std::string original_lang = helper->language_state().original_language(); std::string target_lang = g_browser_process->GetApplicationLocale(); target_lang = TranslateManager::GetLanguageCode(target_lang); // Since the user decided to translate for that language and site, clears diff --git a/chrome/browser/translate/translate_infobar_delegate.cc b/chrome/browser/translate/translate_infobar_delegate.cc index e0a49fe..1835872 100644 --- a/chrome/browser/translate/translate_infobar_delegate.cc +++ b/chrome/browser/translate/translate_infobar_delegate.cc @@ -11,6 +11,8 @@ #include "chrome/browser/profiles/profile.h" #include "chrome/browser/translate/translate_infobar_view.h" #include "chrome/browser/translate/translate_manager.h" +#include "chrome/browser/translate/translate_tab_helper.h" +#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" #include "chrome/common/chrome_constants.h" #include "content/browser/tab_contents/tab_contents.h" #include "grit/generated_resources.h" @@ -128,7 +130,9 @@ void TranslateInfoBarDelegate::TranslationDeclined() { // translations when getting a LANGUAGE_DETERMINED from the page, which // happens when a load stops. That could happen multiple times, including // after the user already declined the translation.) - tab_contents_->language_state().set_translation_declined(true); + TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents( + tab_contents_)->translate_tab_helper(); + helper->language_state().set_translation_declined(true); } bool TranslateInfoBarDelegate::IsLanguageBlacklisted() { diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc index d6ba832..3322ca02 100644 --- a/chrome/browser/translate/translate_manager.cc +++ b/chrome/browser/translate/translate_manager.cc @@ -14,10 +14,12 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profiles/profile.h" +#include "chrome/browser/tab_contents/language_state.h" #include "chrome/browser/tab_contents/tab_util.h" #include "chrome/browser/tabs/tab_strip_model.h" #include "chrome/browser/translate/page_translated_details.h" #include "chrome/browser/translate/translate_infobar_delegate.h" +#include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/translate/translate_prefs.h" #include "chrome/browser/ui/browser.h" #include "chrome/browser/ui/browser_list.h" @@ -29,7 +31,6 @@ #include "chrome/common/url_constants.h" #include "content/browser/renderer_host/render_process_host.h" #include "content/browser/renderer_host/render_view_host.h" -#include "content/browser/tab_contents/language_state.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/navigation_entry.h" #include "content/browser/tab_contents/tab_contents.h" @@ -208,8 +209,16 @@ void TranslateManager::Observe(NotificationType type, NOTREACHED(); return; } + + TabContentsWrapper* wrapper = + TabContentsWrapper::GetCurrentWrapperForContents( + controller->tab_contents()); + if (!wrapper || !wrapper->translate_tab_helper()) + return; + + TranslateTabHelper* helper = wrapper->translate_tab_helper(); if (!load_details->is_main_frame && - controller->tab_contents()->language_state().translation_declined()) { + helper->language_state().translation_declined()) { // Some sites (such as Google map) may trigger sub-frame navigations // when the user interacts with the page. We don't want to show a new // infobar if the user already dismissed one in that case. @@ -230,15 +239,17 @@ void TranslateManager::Observe(NotificationType type, &TranslateManager::InitiateTranslationPosted, controller->tab_contents()->render_view_host()->process()->id(), controller->tab_contents()->render_view_host()->routing_id(), - controller->tab_contents()->language_state(). - original_language())); + helper->language_state().original_language())); break; } case NotificationType::TAB_LANGUAGE_DETERMINED: { TabContents* tab = Source<TabContents>(source).ptr(); // We may get this notifications multiple times. Make sure to translate // only once. - LanguageState& language_state = tab->language_state(); + TabContentsWrapper* wrapper = + TabContentsWrapper::GetCurrentWrapperForContents(tab); + LanguageState& language_state = + wrapper->translate_tab_helper()->language_state(); if (language_state.page_translatable() && !language_state.translation_pending() && !language_state.translation_declined() && @@ -407,7 +418,9 @@ void TranslateManager::InitiateTranslation(TabContents* tab, return; } - std::string auto_translate_to = tab->language_state().AutoTranslateTo(); + TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents( + tab)->translate_tab_helper(); + std::string auto_translate_to = helper->language_state().AutoTranslateTo(); if (!auto_translate_to.empty()) { // This page was navigated through a click from a translated page. TranslatePage(tab, page_lang, auto_translate_to); @@ -423,7 +436,12 @@ void TranslateManager::InitiateTranslationPosted( int process_id, int render_id, const std::string& page_lang) { // The tab might have been closed. TabContents* tab = tab_util::GetTabContentsByID(process_id, render_id); - if (!tab || tab->language_state().translation_pending()) + if (!tab) + return; + + TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents( + tab)->translate_tab_helper(); + if (helper->language_state().translation_pending()) return; InitiateTranslation(tab, page_lang); @@ -476,8 +494,11 @@ void TranslateManager::RevertTranslation(TabContents* tab_contents) { } tab_contents->render_view_host()->Send(new ViewMsg_RevertTranslation( tab_contents->render_view_host()->routing_id(), entry->page_id())); - tab_contents->language_state().set_current_language( - tab_contents->language_state().original_language()); + + TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents( + tab_contents)->translate_tab_helper(); + helper->language_state().set_current_language( + helper->language_state().original_language()); } void TranslateManager::ReportLanguageDetectionError(TabContents* tab_contents) { @@ -487,7 +508,10 @@ void TranslateManager::ReportLanguageDetectionError(TabContents* tab_contents) { report_error_url += "?client=cr&action=langidc&u="; report_error_url += EscapeUrlEncodedData(page_url.spec()); report_error_url += "&sl="; - report_error_url += tab_contents->language_state().original_language(); + + TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents( + tab_contents)->translate_tab_helper(); + report_error_url += helper->language_state().original_language(); report_error_url += "&hl="; report_error_url += GetLanguageCode(g_browser_process->GetApplicationLocale()); @@ -511,8 +535,11 @@ void TranslateManager::DoTranslatePage(TabContents* tab, return; } - tab->language_state().set_translation_pending(true); + TabContentsWrapper* wrapper = + TabContentsWrapper::GetCurrentWrapperForContents(tab); + wrapper->translate_tab_helper()->language_state().set_translation_pending( + true); tab->render_view_host()->Send(new ViewMsg_TranslatePage( tab->render_view_host()->routing_id(), entry->page_id(), translate_script, source_lang, target_lang)); @@ -521,8 +548,6 @@ void TranslateManager::DoTranslatePage(TabContents* tab, // but we don't have that yet. So before start translation, we clear the // current form and re-parse it in AutofillManager first to get the new // labels. - TabContentsWrapper* wrapper = - TabContentsWrapper::GetCurrentWrapperForContents(tab); if (wrapper) wrapper->autofill_manager()->Reset(); } diff --git a/chrome/browser/translate/translate_manager_browsertest.cc b/chrome/browser/translate/translate_manager_browsertest.cc index 7c37430..afbd9ff 100644 --- a/chrome/browser/translate/translate_manager_browsertest.cc +++ b/chrome/browser/translate/translate_manager_browsertest.cc @@ -13,6 +13,7 @@ #include "chrome/browser/translate/translate_infobar_delegate.h" #include "chrome/browser/translate/translate_manager.h" #include "chrome/browser/translate/translate_prefs.h" +#include "chrome/browser/ui/tab_contents/test_tab_contents_wrapper.h" #include "chrome/common/pref_names.h" #include "chrome/common/render_messages.h" #include "chrome/common/net/test_url_fetcher_factory.h" @@ -39,7 +40,7 @@ using testing::Pointee; using testing::Property; using WebKit::WebContextMenuData; -class TranslateManagerTest : public RenderViewHostTestHarness, +class TranslateManagerTest : public TabContentsWrapperTestHarness, public NotificationObserver { public: TranslateManagerTest() @@ -49,23 +50,16 @@ class TranslateManagerTest : public RenderViewHostTestHarness, // Simluates navigating to a page and getting the page contents and language // for that navigation. void SimulateNavigation(const GURL& url, - const std::string& contents, const std::string& lang, bool page_translatable) { NavigateAndCommit(url); - int page_id = RenderViewHostTestHarness::contents()->controller(). - GetLastCommittedEntry()->page_id(); - SimulateOnPageContents(url, page_id, contents, lang, page_translatable); + SimulateOnTranslateLanguageDetermined(lang, page_translatable); } - void SimulateOnPageContents(const GURL& url, int page_id, - const std::string& contents, - const std::string& lang, - bool page_translatable) { - rvh()->TestOnMessageReceived(ViewHostMsg_PageContents(0, url, page_id, - UTF8ToUTF16(contents), - lang, - page_translatable)); + void SimulateOnTranslateLanguageDetermined(const std::string& lang, + bool page_translatable) { + rvh()->TestOnMessageReceived(ViewHostMsg_TranslateLanguageDetermined( + 0, lang, page_translatable)); } bool GetTranslateMessage(int* page_id, @@ -162,7 +156,7 @@ class TranslateManagerTest : public RenderViewHostTestHarness, TranslateManager::GetInstance()-> set_translate_script_expiration_delay(60 * 60 * 1000); - RenderViewHostTestHarness::SetUp(); + TabContentsWrapperTestHarness::SetUp(); notification_registrar_.Add(this, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, @@ -176,7 +170,7 @@ class TranslateManagerTest : public RenderViewHostTestHarness, NotificationType::TAB_CONTENTS_INFOBAR_REMOVED, Source<TabContents>(contents())); - RenderViewHostTestHarness::TearDown(); + TabContentsWrapperTestHarness::TearDown(); URLFetcher::set_factory(NULL); } @@ -285,7 +279,7 @@ class TestRenderViewContextMenu : public RenderViewContextMenu { TEST_F(TranslateManagerTest, NormalTranslate) { // Simulate navigating to a page. - SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // We should have an infobar. TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); @@ -353,7 +347,7 @@ TEST_F(TranslateManagerTest, NormalTranslate) { TEST_F(TranslateManagerTest, TranslateScriptNotAvailable) { // Simulate navigating to a page. - SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // We should have an infobar. TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); @@ -380,7 +374,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"), "G00g1e", "und", true); + SimulateNavigation(GURL("http://www.google.mys"), "und", true); // We should not have an infobar as we don't know the language. ASSERT_TRUE(GetTranslateInfoBar() == NULL); @@ -414,7 +408,7 @@ 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"), "The Google", "und", true); + SimulateNavigation(GURL("http://www.google.com"), "und", true); menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); menu->Init(); menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); @@ -427,7 +421,7 @@ 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"), "The Google", "und", true); + SimulateNavigation(GURL("http://www.google.com"), "und", true); menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); menu->Init(); menu->ExecuteCommand(IDC_CONTENT_CONTEXT_TRANSLATE); @@ -497,7 +491,7 @@ TEST_F(TranslateManagerTest, TestAllLanguages) { // Simulate navigating to a page. NavigateAndCommit(url); - SimulateOnPageContents(url, i, "", lang, true); + SimulateOnTranslateLanguageDetermined(lang, true); // Verify we have/don't have an info-bar as expected. infobar = GetTranslateInfoBar(); @@ -512,7 +506,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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // Simulate the user translating. TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); @@ -525,7 +519,7 @@ TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) { // Now navigate to a new page in the same language. process()->sink().ClearMessages(); - SimulateNavigation(GURL("http://news.google.fr"), "Les news", "fr", true); + SimulateNavigation(GURL("http://news.google.fr"), "fr", true); // This should have automatically triggered a translation. int page_id = 0; @@ -537,7 +531,7 @@ TEST_F(TranslateManagerTest, AutoTranslateOnNavigate) { // Now navigate to a page in a different language. process()->sink().ClearMessages(); - SimulateNavigation(GURL("http://news.google.es"), "Las news", "es", true); + SimulateNavigation(GURL("http://news.google.es"), "es", true); // This should not have triggered a translate. EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); @@ -546,31 +540,28 @@ 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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // Simulate clicking 'Nope' (don't translate). EXPECT_TRUE(DenyTranslation()); EXPECT_EQ(0U, contents()->infobar_count()); // Send a new PageContents, we should not show an infobar. - SimulateOnPageContents(GURL("http://www.google.fr"), 0, "Le Google", "fr", - true); + SimulateOnTranslateLanguageDetermined("fr", true); EXPECT_EQ(0U, contents()->infobar_count()); // Do the same steps but simulate closing the infobar this time. - SimulateNavigation(GURL("http://www.youtube.fr"), "Le YouTube", "fr", - true); + SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true); EXPECT_TRUE(CloseTranslateInfoBar()); EXPECT_EQ(0U, contents()->infobar_count()); - SimulateOnPageContents(GURL("http://www.youtube.fr"), 1, "Le YouTube", "fr", - true); + SimulateOnTranslateLanguageDetermined("fr", true); EXPECT_EQ(0U, contents()->infobar_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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // Close the infobar. EXPECT_TRUE(CloseTranslateInfoBar()); @@ -597,7 +588,7 @@ TEST_F(TranslateManagerTest, ReloadFromLocationBar) { GURL url("http://www.google.fr"); // Simulate navigating to a page and getting its language. - SimulateNavigation(url, "Le Google", "fr", true); + SimulateNavigation(url, "fr", true); // Close the infobar. EXPECT_TRUE(CloseTranslateInfoBar()); @@ -625,19 +616,18 @@ 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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // Close the infobar. EXPECT_TRUE(CloseTranslateInfoBar()); // Navigate in page, no infobar should be shown. - SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", + SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); EXPECT_TRUE(GetTranslateInfoBar() == NULL); // Navigate out of page, a new infobar should show. - SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", - true); + SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); EXPECT_TRUE(GetTranslateInfoBar() != NULL); } @@ -645,7 +635,7 @@ TEST_F(TranslateManagerTest, CloseInfoBarInPageNavigation) { // in a subframe. (http://crbug.com/48215) TEST_F(TranslateManagerTest, CloseInfoBarInSubframeNavigation) { // Simulate navigating to a page and getting its language. - SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // Close the infobar. EXPECT_TRUE(CloseTranslateInfoBar()); @@ -661,8 +651,7 @@ TEST_F(TranslateManagerTest, CloseInfoBarInSubframeNavigation) { EXPECT_TRUE(GetTranslateInfoBar() == NULL); // Navigate out of page, a new infobar should show. - SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", - true); + SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); EXPECT_TRUE(GetTranslateInfoBar() != NULL); } @@ -671,19 +660,17 @@ TEST_F(TranslateManagerTest, CloseInfoBarInSubframeNavigation) { // 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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "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"), "Le Google", "fr", - true); + SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); EXPECT_TRUE(GetTranslateInfoBar() == NULL); // Navigate out of page, a new infobar should show. - SimulateNavigation(GURL("http://www.google.fr/foot"), "Le Google", "fr", - true); + SimulateNavigation(GURL("http://www.google.fr/foot"), "fr", true); EXPECT_TRUE(GetTranslateInfoBar() != NULL); } @@ -691,7 +678,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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // Simulate the user translating. TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); @@ -705,15 +692,14 @@ TEST_F(TranslateManagerTest, TranslateCloseInfoBarInPageNavigation) { EXPECT_TRUE(CloseTranslateInfoBar()); // Navigate in page, no infobar should be shown. - SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", - true); + SimulateNavigation(GURL("http://www.google.fr/#ref1"), "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"), "Das Google", "de", true); + SimulateNavigation(GURL("http://www.google.de"), "de", true); EXPECT_TRUE(GetTranslateInfoBar() != NULL); } @@ -721,7 +707,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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // Simulate the user translating. TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); @@ -736,7 +722,7 @@ TEST_F(TranslateManagerTest, TranslateInPageNavigation) { // Navigate in page, the same infobar should still be shown. ClearRemovedInfoBars(); - SimulateNavigation(GURL("http://www.google.fr/#ref1"), "Le Google", "fr", + SimulateNavigation(GURL("http://www.google.fr/#ref1"), "fr", true); EXPECT_FALSE(InfoBarRemoved()); EXPECT_EQ(infobar, GetTranslateInfoBar()); @@ -744,7 +730,7 @@ TEST_F(TranslateManagerTest, TranslateInPageNavigation) { // 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"), "Das Google", "de", true); + SimulateNavigation(GURL("http://www.google.de"), "de", true); // The old infobar is gone. EXPECT_TRUE(CheckInfoBarRemovedAndReset(infobar)); // And there is a new one. @@ -755,7 +741,7 @@ TEST_F(TranslateManagerTest, TranslateInPageNavigation) { // unsupported language. TEST_F(TranslateManagerTest, CLDReportsUnsupportedPageLanguage) { // Simulate navigating to a page and getting an unsupported language. - SimulateNavigation(GURL("http://www.google.com"), "Google", "qbz", true); + SimulateNavigation(GURL("http://www.google.com"), "qbz", true); // No info-bar should be shown. EXPECT_TRUE(GetTranslateInfoBar() == NULL); @@ -766,7 +752,7 @@ TEST_F(TranslateManagerTest, CLDReportsUnsupportedPageLanguage) { // The translation server might return a language we don't support. TEST_F(TranslateManagerTest, ServerReportsUnsupportedLanguage) { // Simulate navigating to a page and translating it. - SimulateNavigation(GURL("http://mail.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://mail.google.fr"), "fr", true); TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); process()->sink().ClearMessages(); @@ -806,7 +792,7 @@ TEST_F(TranslateManagerTest, UnsupportedUILanguage) { // Simulate navigating to a page in a language supported by the translate // server. - SimulateNavigation(GURL("http://www.google.com"), "Google", "en", true); + SimulateNavigation(GURL("http://www.google.com"), "en", true); // No info-bar should be shown. EXPECT_TRUE(GetTranslateInfoBar() == NULL); @@ -821,7 +807,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"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // An infobar should be shown. TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); @@ -838,7 +824,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", true); + SimulateOnTranslateLanguageDetermined("fr", true); infobar = GetTranslateInfoBar(); EXPECT_TRUE(infobar == NULL); } @@ -847,7 +833,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, "Le Google", "fr", true); + SimulateNavigation(url, "fr", true); // An infobar should be shown. EXPECT_TRUE(GetTranslateInfoBar() != NULL); @@ -870,7 +856,7 @@ TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) { EXPECT_TRUE(CloseTranslateInfoBar()); // Navigate to a new page also in French. - SimulateNavigation(GURL("http://wwww.youtube.fr"), "Le YouTube", "fr", true); + SimulateNavigation(GURL("http://wwww.youtube.fr"), "fr", true); // There should not be a translate infobar. EXPECT_TRUE(GetTranslateInfoBar() == NULL); @@ -882,7 +868,7 @@ TEST_F(TranslateManagerTest, NeverTranslateLanguagePref) { EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); // Navigate to a page in French. - SimulateNavigation(url, "Le Google", "fr", true); + SimulateNavigation(url, "fr", true); // There should be a translate infobar. EXPECT_TRUE(GetTranslateInfoBar() != NULL); @@ -893,7 +879,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, "Le Google", "fr", true); + SimulateNavigation(url, "fr", true); // An infobar should be shown. EXPECT_TRUE(GetTranslateInfoBar() != NULL); @@ -916,7 +902,7 @@ TEST_F(TranslateManagerTest, NeverTranslateSitePref) { EXPECT_TRUE(CloseTranslateInfoBar()); // Navigate to a new page also on the same site. - SimulateNavigation(GURL("http://www.google.fr/hello"), "Bonjour", "fr", true); + SimulateNavigation(GURL("http://www.google.fr/hello"), "fr", true); // There should not be a translate infobar. EXPECT_TRUE(GetTranslateInfoBar() == NULL); @@ -928,7 +914,7 @@ TEST_F(TranslateManagerTest, NeverTranslateSitePref) { EXPECT_TRUE(translate_prefs.CanTranslate(prefs, "fr", url)); // Navigate to a page in French. - SimulateNavigation(url, "Le Google", "fr", true); + SimulateNavigation(url, "fr", true); // There should be a translate infobar. EXPECT_TRUE(GetTranslateInfoBar() != NULL); @@ -947,7 +933,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) { translate_prefs.WhitelistLanguagePair("fr", "en"); // Load a page in French. - SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); // It should have triggered an automatic translation to English. @@ -965,7 +951,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) { process()->sink().ClearMessages(); // Try another language, it should not be autotranslated. - SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); + SimulateNavigation(GURL("http://www.google.es"), "es", true); EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); EXPECT_TRUE(GetTranslateInfoBar() != NULL); EXPECT_TRUE(CloseTranslateInfoBar()); @@ -975,7 +961,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) { TestingProfile* test_profile = static_cast<TestingProfile*>(contents()->profile()); test_profile->set_incognito(true); - SimulateNavigation(GURL("http://www.youtube.fr"), "Le YouTube", "fr", true); + SimulateNavigation(GURL("http://www.youtube.fr"), "fr", true); EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); EXPECT_TRUE(GetTranslateInfoBar() != NULL); EXPECT_TRUE(CloseTranslateInfoBar()); @@ -985,7 +971,7 @@ TEST_F(TranslateManagerTest, AlwaysTranslateLanguagePref) { // behavior, which is show a "before translate" infobar. SetPrefObserverExpectation(TranslatePrefs::kPrefTranslateWhitelists); translate_prefs.RemoveLanguagePairFromWhitelist("fr", "en"); - SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); EXPECT_FALSE(GetTranslateMessage(&page_id, &original_lang, &target_lang)); infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); @@ -1012,7 +998,7 @@ TEST_F(TranslateManagerTest, ContextMenu) { EXPECT_FALSE(menu->IsCommandIdEnabled(IDC_CONTENT_CONTEXT_TRANSLATE)); // Simulate receiving the language. - SimulateOnPageContents(url, 0, "Le Google", "fr", true); + SimulateOnTranslateLanguageDetermined("fr", true); menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); menu->Init(); EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); @@ -1051,7 +1037,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"), "El Google", "es", true); + SimulateNavigation(GURL("http://www.google.es"), "es", true); infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); infobar->Translate(); @@ -1066,7 +1052,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"), "Das Google", "de", true); + SimulateNavigation(GURL("http://www.google.de"), "de", true); infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); infobar->Translate(); @@ -1083,7 +1069,7 @@ TEST_F(TranslateManagerTest, ContextMenu) { // Test that the translate context menu is enabled when the page is in an // unknown language. - SimulateNavigation(url, "G00g1e", "und", true); + SimulateNavigation(url, "und", true); menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); menu->Init(); EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); @@ -1091,7 +1077,7 @@ TEST_F(TranslateManagerTest, ContextMenu) { // Test that the translate context menu is disabled when the page is in an // unsupported language. - SimulateNavigation(url, "G00g1e", "qbz", true); + SimulateNavigation(url, "qbz", true); menu.reset(TestRenderViewContextMenu::CreateContextMenu(contents())); menu->Init(); EXPECT_TRUE(menu->IsItemPresent(IDC_CONTENT_CONTEXT_TRANSLATE)); @@ -1117,7 +1103,7 @@ TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) { for (int i = 0; i < 8; ++i) { SCOPED_TRACE(::testing::Message() << "Iteration " << i << " incognito mode=" << test_profile->IsOffTheRecord()); - SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); @@ -1149,7 +1135,7 @@ TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) { for (int i = 0; i < 8; ++i) { SCOPED_TRACE(::testing::Message() << "Iteration " << i << " incognito mode=" << test_profile->IsOffTheRecord()); - SimulateNavigation(GURL("http://www.google.de"), "Das Google", "de", true); + SimulateNavigation(GURL("http://www.google.de"), "de", true); infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); EXPECT_EQ(TranslateInfoBarDelegate::BEFORE_TRANSLATE, infobar->type()); @@ -1175,7 +1161,7 @@ TEST_F(TranslateManagerTest, BeforeTranslateExtraButtons) { // should not be translated. TEST_F(TranslateManagerTest, NonTranslatablePage) { // Simulate navigating to a page. - SimulateNavigation(GURL("http://mail.google.fr"), "Le Google", "fr", false); + SimulateNavigation(GURL("http://mail.google.fr"), "fr", false); // We should not have an infobar. EXPECT_TRUE(GetTranslateInfoBar() == NULL); @@ -1193,7 +1179,7 @@ TEST_F(TranslateManagerTest, ScriptExpires) { ExpireTranslateScriptImmediately(); // Simulate navigating to a page and translating it. - SimulateNavigation(GURL("http://www.google.fr"), "Le Google", "fr", true); + SimulateNavigation(GURL("http://www.google.fr"), "fr", true); TranslateInfoBarDelegate* infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); process()->sink().ClearMessages(); @@ -1206,7 +1192,7 @@ TEST_F(TranslateManagerTest, ScriptExpires) { MessageLoop::current()->RunAllPending(); // Do another navigation and translation. - SimulateNavigation(GURL("http://www.google.es"), "El Google", "es", true); + SimulateNavigation(GURL("http://www.google.es"), "es", true); infobar = GetTranslateInfoBar(); ASSERT_TRUE(infobar != NULL); process()->sink().ClearMessages(); diff --git a/chrome/browser/translate/translate_tab_helper.cc b/chrome/browser/translate/translate_tab_helper.cc new file mode 100644 index 0000000..d7ec4fc --- /dev/null +++ b/chrome/browser/translate/translate_tab_helper.cc @@ -0,0 +1,61 @@ +// Copyright (c) 2011 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/translate/translate_tab_helper.h" + +#include "chrome/browser/translate/page_translated_details.h" +#include "chrome/common/render_messages.h" +#include "content/browser/tab_contents/tab_contents.h" +#include "content/common/notification_service.h" + +TranslateTabHelper::TranslateTabHelper(TabContents* tab_contents) + : TabContentsObserver(tab_contents), + language_state_(&tab_contents->controller()) { +} + +TranslateTabHelper::~TranslateTabHelper() { +} + +bool TranslateTabHelper::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(TranslateTabHelper, message) + IPC_MESSAGE_HANDLER(ViewHostMsg_TranslateLanguageDetermined, + OnLanguageDetermined) + IPC_MESSAGE_HANDLER(ViewHostMsg_PageTranslated, OnPageTranslated) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + return handled; +} + +void TranslateTabHelper::DidNavigateAnyFramePostCommit( + const NavigationController::LoadCommittedDetails& details, + const ViewHostMsg_FrameNavigate_Params& params) { + // Let the LanguageState clear its state. + language_state_.DidNavigate(details); +} + +void TranslateTabHelper::OnLanguageDetermined(const std::string& language, + bool page_translatable) { + language_state_.LanguageDetermined(language, page_translatable); + + std::string lang = language; + NotificationService::current()->Notify( + NotificationType::TAB_LANGUAGE_DETERMINED, + Source<TabContents>(tab_contents()), + Details<std::string>(&lang)); +} + +void TranslateTabHelper::OnPageTranslated(int32 page_id, + const std::string& original_lang, + const std::string& translated_lang, + TranslateErrors::Type error_type) { + language_state_.set_current_language(translated_lang); + language_state_.set_translation_pending(false); + PageTranslatedDetails details(original_lang, translated_lang, error_type); + NotificationService::current()->Notify( + NotificationType::PAGE_TRANSLATED, + Source<TabContents>(tab_contents()), + Details<PageTranslatedDetails>(&details)); +} diff --git a/chrome/browser/translate/translate_tab_helper.h b/chrome/browser/translate/translate_tab_helper.h new file mode 100644 index 0000000..874f47d --- /dev/null +++ b/chrome/browser/translate/translate_tab_helper.h @@ -0,0 +1,40 @@ +// Copyright (c) 2011 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_TRANSLATE_TRANSLATE_TAB_HELPER_H_ +#define CHROME_BROWSER_TRANSLATE_TRANSLATE_TAB_HELPER_H_ +#pragma once + +#include "chrome/browser/tab_contents/language_state.h" +#include "chrome/common/translate_errors.h" +#include "content/browser/tab_contents/tab_contents_observer.h" + +class TranslateTabHelper : public TabContentsObserver { + public: + explicit TranslateTabHelper(TabContents* tab_contents); + ~TranslateTabHelper(); + + LanguageState& language_state() { return language_state_; } + + private: + // TabContentsObserver implementation. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void DidNavigateAnyFramePostCommit( + const NavigationController::LoadCommittedDetails& details, + const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE; + + void OnLanguageDetermined(const std::string& language, + bool page_translatable); + void OnPageTranslated(int32 page_id, + const std::string& original_lang, + const std::string& translated_lang, + TranslateErrors::Type error_type); + + // Information about the language the page is in and has been translated to. + LanguageState language_state_; + + DISALLOW_COPY_AND_ASSIGN(TranslateTabHelper); +}; + +#endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_TAB_HELPER_H_ diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc index c19c416..1b7ad45 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc @@ -13,6 +13,7 @@ #include "chrome/browser/custom_handlers/register_protocol_handler_infobar_delegate.h" #include "chrome/browser/extensions/extension_tab_helper.h" #include "chrome/browser/file_select_helper.h" +#include "chrome/browser/history/history.h" #include "chrome/browser/history/top_sites.h" #include "chrome/browser/password_manager/password_manager.h" #include "chrome/browser/password_manager_delegate_impl.h" @@ -21,6 +22,7 @@ #include "chrome/browser/printing/print_preview_message_handler.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/tab_contents/simple_alert_infobar_delegate.h" +#include "chrome/browser/translate/translate_tab_helper.h" #include "chrome/browser/ui/download/download_tab_helper.h" #include "chrome/browser/ui/find_bar/find_tab_helper.h" #include "chrome/browser/ui/search_engines/search_engine_tab_helper.h" @@ -62,6 +64,7 @@ TabContentsWrapper::TabContentsWrapper(TabContents* contents) password_manager_.reset( new PasswordManager(contents, password_manager_delegate_.get())); search_engine_tab_helper_.reset(new SearchEngineTabHelper(contents)); + translate_tab_helper_.reset(new TranslateTabHelper(contents)); print_view_manager_.reset(new printing::PrintViewManager(contents)); // Register for notifications about URL starredness changing on any profile. @@ -215,6 +218,7 @@ void TabContentsWrapper::DidNavigateMainFramePostCommit( bool TabContentsWrapper::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(TabContentsWrapper, message) + IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents) IPC_MESSAGE_HANDLER(ViewHostMsg_JSOutOfMemory, OnJSOutOfMemory) IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler, OnRegisterProtocolHandler) @@ -252,6 +256,29 @@ void TabContentsWrapper::Observe(NotificationType type, //////////////////////////////////////////////////////////////////////////////// // Internal helpers +void TabContentsWrapper::OnPageContents(const GURL& url, + int32 page_id, + const string16& contents) { + // 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. + // TODO(brettw) we may want to consider more elaborate heuristics such as + // the cachability of the page. We may also want to consider subframes (this + // test will still index subframes if the subframe is SSL). + // TODO(zelidrag) bug chromium-os:2808 - figure out if we want to reenable + // content indexing for chromeos in some future releases. +#if !defined(OS_CHROMEOS) + if (!url.SchemeIsSecure()) { + Profile* p = profile(); + if (p && !p->IsOffTheRecord()) { + HistoryService* hs = p->GetHistoryService(Profile::IMPLICIT_ACCESS); + if (hs) + hs->SetPageContents(url, contents); + } + } +#endif +} + void TabContentsWrapper::OnJSOutOfMemory() { tab_contents()->AddInfoBar(new SimpleAlertInfoBarDelegate(tab_contents(), NULL, l10n_util::GetStringUTF16(IDS_JS_OUT_OF_MEMORY_PROMPT), true)); diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h index 75b9211..8134e8d 100644 --- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h +++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h @@ -37,6 +37,7 @@ class PasswordManager; class PasswordManagerDelegate; class SearchEngineTabHelper; class TabContentsWrapperDelegate; +class TranslateTabHelper; // Wraps TabContents and all of its supporting objects in order to control // their ownership and lifetime, while allowing TabContents to remain generic @@ -124,6 +125,10 @@ class TabContentsWrapper : public NotificationObserver, return search_engine_tab_helper_.get(); } + TranslateTabHelper* translate_tab_helper() { + return translate_tab_helper_.get(); + } + // Overrides ----------------------------------------------------------------- // TabContentsObserver overrides: @@ -141,6 +146,9 @@ class TabContentsWrapper : public NotificationObserver, // Internal helpers ---------------------------------------------------------- // Message handlers. + void OnPageContents(const GURL& url, + int32 page_id, + const string16& contents); void OnJSOutOfMemory(); void OnRegisterProtocolHandler(const std::string& protocol, const GURL& url, @@ -186,6 +194,7 @@ class TabContentsWrapper : public NotificationObserver, scoped_ptr<printing::PrintViewManager> print_view_manager_; scoped_ptr<SearchEngineTabHelper> search_engine_tab_helper_; + scoped_ptr<TranslateTabHelper> translate_tab_helper_; // Per-tab observers --------------------------------------------------------- // (These provide no API for callers; objects that need to exist 1:1 with tabs diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 9525a26..4fccf0f 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1971,6 +1971,8 @@ 'browser/tab_contents/confirm_infobar_delegate.h', 'browser/tab_contents/infobar_delegate.cc', 'browser/tab_contents/infobar_delegate.h', + 'browser/tab_contents/language_state.cc', + 'browser/tab_contents/language_state.h', 'browser/tab_contents/link_infobar_delegate.cc', 'browser/tab_contents/link_infobar_delegate.h', 'browser/tab_contents/simple_alert_infobar_delegate.cc', @@ -2046,6 +2048,8 @@ 'browser/translate/translate_manager.h', 'browser/translate/translate_prefs.cc', 'browser/translate/translate_prefs.h', + 'browser/translate/translate_tab_helper.cc', + 'browser/translate/translate_tab_helper.h', 'browser/transport_security_persister.cc', 'browser/transport_security_persister.h', 'browser/ui/app_modal_dialogs/app_modal_dialog.cc', diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi index 591d5ac..5bcb197 100644 --- a/chrome/chrome_renderer.gypi +++ b/chrome/chrome_renderer.gypi @@ -95,6 +95,8 @@ 'renderer/blocked_plugin.h', 'renderer/chrome_content_renderer_client.cc', 'renderer/chrome_content_renderer_client.h', + 'renderer/chrome_render_observer.cc', + 'renderer/chrome_render_observer.h', 'renderer/devtools_agent.cc', 'renderer/devtools_agent.h', 'renderer/devtools_agent_filter.cc', diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index d417048..9301559 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -315,6 +315,17 @@ IPC_MESSAGE_CONTROL1(ViewMsg_SetIsIncognitoProcess, // TabContents messages // These are messages sent from the renderer to the browser process. +// Provides the contents for the given page that was loaded recently. +IPC_MESSAGE_ROUTED3(ViewHostMsg_PageContents, + GURL /* URL of the page */, + int32 /* page id */, + string16 /* page contents */) + +// Notification that the language for the tab has been determined. +IPC_MESSAGE_ROUTED2(ViewHostMsg_TranslateLanguageDetermined, + std::string /* page ISO639_1 language code */, + bool /* whether the page can be translated */) + IPC_MESSAGE_CONTROL1(ViewHostMsg_UpdatedCacheStats, WebKit::WebCache::UsageStats /* stats */) diff --git a/chrome/renderer/autofill/autofill_agent.h b/chrome/renderer/autofill/autofill_agent.h index c3255fb..ba7dba9 100644 --- a/chrome/renderer/autofill/autofill_agent.h +++ b/chrome/renderer/autofill/autofill_agent.h @@ -38,6 +38,10 @@ class AutofillAgent : public RenderViewObserver, PasswordAutofillManager* password_autofill_manager); virtual ~AutofillAgent(); + // Called when the translate helper has finished translating the page. We + // use this signal to re-scan the page for forms. + void FrameTranslated(WebKit::WebFrame* frame); + // WebKit::WebAutoFillClient implementation. Public for tests. virtual void didAcceptAutoFillSuggestion(const WebKit::WebNode& node, const WebKit::WebString& value, @@ -71,7 +75,6 @@ class AutofillAgent : public RenderViewObserver, virtual void FrameWillClose(WebKit::WebFrame* frame); virtual void WillSubmitForm(WebKit::WebFrame* frame, const WebKit::WebFormElement& form); - virtual void FrameTranslated(WebKit::WebFrame* frame); // PageClickListener implementation: virtual bool InputElementClicked(const WebKit::WebInputElement& element, diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 0703b7b..42cdbfc 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -9,7 +9,6 @@ #include "base/command_line.h" #include "base/metrics/histogram.h" #include "base/values.h" -#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" @@ -22,6 +21,7 @@ #include "chrome/renderer/autofill/password_autofill_manager.h" #include "chrome/renderer/automation/automation_renderer_helper.h" #include "chrome/renderer/blocked_plugin.h" +#include "chrome/renderer/chrome_render_observer.h" #include "chrome/renderer/devtools_agent.h" #include "chrome/renderer/extensions/bindings_utils.h" #include "chrome/renderer/extensions/event_bindings.h" @@ -48,7 +48,6 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" -#include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h" #include "ui/base/l10n/l10n_util.h" #include "ui/base/resource/resource_bundle.h" #include "webkit/plugins/npapi/plugin_list.h" @@ -93,7 +92,20 @@ static bool CrossesExtensionExtents(WebFrame* frame, const GURL& new_url) { namespace chrome { void ChromeContentRendererClient::RenderViewCreated(RenderView* render_view) { + safe_browsing::PhishingClassifierDelegate* phishing_classifier = NULL; +#ifndef OS_CHROMEOS + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableClientSidePhishingDetection)) { + phishing_classifier = + new safe_browsing::PhishingClassifierDelegate(render_view, NULL); + } +#endif + new DevToolsAgent(render_view); + new ExtensionHelper(render_view); + new PrintWebViewHelper(render_view); + new SearchBox(render_view); + new safe_browsing::MalwareDOMDetails(render_view); PasswordAutofillManager* password_autofill_manager = new PasswordAutofillManager(render_view); @@ -106,23 +118,8 @@ void ChromeContentRendererClient::RenderViewCreated(RenderView* render_view) { page_click_tracker->AddListener(password_autofill_manager); page_click_tracker->AddListener(autofill_agent); - new TranslateHelper(render_view); - -#ifndef OS_CHROMEOS - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kDisableClientSidePhishingDetection)) { - new safe_browsing::PhishingClassifierDelegate(render_view, NULL); - } -#endif - - // Observer for Malware DOM details messages. - new safe_browsing::MalwareDOMDetails(render_view); - - new ExtensionHelper(render_view); - - new PrintWebViewHelper(render_view); - - new SearchBox(render_view); + TranslateHelper* translate = new TranslateHelper(render_view, autofill_agent); + new ChromeRenderObserver(render_view, translate, phishing_classifier); // Used only for testing/automation. if (CommandLine::ForCurrentProcess()->HasSwitch( @@ -312,33 +309,6 @@ std::string ChromeContentRendererClient::GetNavigationErrorHtml( return html; } -// Returns the ISO 639_1 language code of the specified |text|, or 'unknown' -// if it failed. -std::string ChromeContentRendererClient::DetermineTextLanguage( - const string16& text) { - std::string language = chrome::kUnknownLanguageCode; - int num_languages = 0; - int text_bytes = 0; - bool is_reliable = false; - Language cld_language = - DetectLanguageOfUnicodeText(NULL, text.c_str(), true, &is_reliable, - &num_languages, NULL, &text_bytes); - // We don't trust the result if the CLD reports that the detection is not - // reliable, or if the actual text used to detect the language was less than - // 100 bytes (short texts can often lead to wrong results). - if (is_reliable && text_bytes >= 100 && cld_language != NUM_LANGUAGES && - cld_language != UNKNOWN_LANGUAGE && cld_language != TG_UNKNOWN_LANGUAGE) { - // We should not use LanguageCode_ISO_639_1 because it does not cover all - // the languages CLD can detect. As a result, it'll return the invalid - // language code for tradtional Chinese among others. - // |LanguageCodeWithDialect| will go through ISO 639-1, ISO-639-2 and - // 'other' tables to do the 'right' thing. In addition, it'll return zh-CN - // for Simplified Chinese. - language = LanguageCodeWithDialects(cld_language); - } - return language; -} - bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() { return !ExtensionDispatcher::Get()->is_extension_process(); } diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h index d69d638..ce6bd04 100644 --- a/chrome/renderer/chrome_content_renderer_client.h +++ b/chrome/renderer/chrome_content_renderer_client.h @@ -28,7 +28,6 @@ class ChromeContentRendererClient : public content::ContentRendererClient { virtual std::string GetNavigationErrorHtml( const WebKit::WebURLRequest& failed_request, const WebKit::WebURLError& error); - virtual std::string DetermineTextLanguage(const string16& text); virtual bool RunIdleHandlerWhenWidgetsHidden(); virtual bool AllowPopup(const GURL& creator); virtual bool ShouldFork(WebKit::WebFrame* frame, diff --git a/chrome/renderer/chrome_render_observer.cc b/chrome/renderer/chrome_render_observer.cc new file mode 100644 index 0000000..ef89792 --- /dev/null +++ b/chrome/renderer/chrome_render_observer.cc @@ -0,0 +1,344 @@ +// Copyright (c) 2011 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/renderer/chrome_render_observer.h" + +#include "base/command_line.h" +#include "base/metrics/histogram.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/render_messages.h" +#include "chrome/common/thumbnail_score.h" +#include "chrome/renderer/safe_browsing/phishing_classifier_delegate.h" +#include "chrome/renderer/translate_helper.h" +#include "content/renderer/content_renderer_client.h" +#include "content/renderer/render_view.h" +#include "skia/ext/bitmap_platform_device.h" +#include "skia/ext/image_operations.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebDataSource.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebRect.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebSize.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" +#include "ui/gfx/color_utils.h" +#include "ui/gfx/skbitmap_operations.h" +#include "webkit/glue/webkit_glue.h" + +using WebKit::WebDataSource; +using WebKit::WebFrame; +using WebKit::WebRect; +using WebKit::WebSize; +using WebKit::WebView; + +// Delay in milliseconds that we'll wait before capturing the page contents +// and thumbnail. +static const int kDelayForCaptureMs = 500; + +// Typically, we capture the page data once the page is loaded. +// Sometimes, the page never finishes to load, preventing the page capture +// To workaround this problem, we always perform a capture after the following +// delay. +static const int kDelayForForcedCaptureMs = 6000; + +// define to write the time necessary for thumbnail/DOM text retrieval, +// respectively, into the system debug log +// #define TIME_TEXT_RETRIEVAL + +// maximum number of characters in the document to index, any text beyond this +// point will be clipped +static const size_t kMaxIndexChars = 65535; + +// Size of the thumbnails that we'll generate +static const int kThumbnailWidth = 212; +static const int kThumbnailHeight = 132; + +static bool PaintViewIntoCanvas(WebView* view, + skia::PlatformCanvas& canvas) { + view->layout(); + const WebSize& size = view->size(); + + if (!canvas.initialize(size.width, size.height, true)) + return false; + + view->paint(webkit_glue::ToWebCanvas(&canvas), + WebRect(0, 0, size.width, size.height)); + // TODO: Add a way to snapshot the whole page, not just the currently + // visible part. + + return true; +} + +// Calculates how "boring" a thumbnail is. The boring score is the +// 0,1 ranged percentage of pixels that are the most common +// luma. Higher boring scores indicate that a higher percentage of a +// bitmap are all the same brightness. +static double CalculateBoringScore(SkBitmap* bitmap) { + int histogram[256] = {0}; + color_utils::BuildLumaHistogram(bitmap, histogram); + + int color_count = *std::max_element(histogram, histogram + 256); + int pixel_count = bitmap->width() * bitmap->height(); + return static_cast<double>(color_count) / pixel_count; +} + +ChromeRenderObserver::ChromeRenderObserver( + RenderView* render_view, + TranslateHelper* translate_helper, + safe_browsing::PhishingClassifierDelegate* phishing_classifier) + : RenderViewObserver(render_view), + translate_helper_(translate_helper), + phishing_classifier_(phishing_classifier), + last_indexed_page_id_(-1), + ALLOW_THIS_IN_INITIALIZER_LIST(page_info_method_factory_(this)) { +} + +ChromeRenderObserver::~ChromeRenderObserver() { +} + +bool ChromeRenderObserver::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(ChromeRenderObserver, message) + IPC_MESSAGE_HANDLER(ViewMsg_CaptureSnapshot, OnCaptureSnapshot) + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +void ChromeRenderObserver::OnCaptureSnapshot() { + SkBitmap snapshot; + bool error = false; + + WebFrame* main_frame = render_view()->webview()->mainFrame(); + if (!main_frame) + error = true; + + if (!error && !CaptureSnapshot(render_view()->webview(), &snapshot)) + error = true; + + DCHECK(error == snapshot.empty()) << + "Snapshot should be empty on error, non-empty otherwise."; + + // Send the snapshot to the browser process. + Send(new ViewHostMsg_Snapshot(routing_id(), snapshot)); +} + +void ChromeRenderObserver::DidStopLoading() { + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + page_info_method_factory_.NewRunnableMethod( + &ChromeRenderObserver::CapturePageInfo, render_view()->page_id(), + false), + render_view()->content_state_immediately() ? 0 : kDelayForCaptureMs); +} + +void ChromeRenderObserver::DidCommitProvisionalLoad(WebFrame* frame, + bool is_new_navigation) { + if (!is_new_navigation) + return; + + MessageLoop::current()->PostDelayedTask( + FROM_HERE, + page_info_method_factory_.NewRunnableMethod( + &ChromeRenderObserver::CapturePageInfo, render_view()->page_id(), + true), + kDelayForForcedCaptureMs); +} + +void ChromeRenderObserver::CapturePageInfo(int load_id, + bool preliminary_capture) { + if (load_id != render_view()->page_id()) + return; // This capture call is no longer relevant due to navigation. + + if (load_id == last_indexed_page_id_) + return; // we already indexed this page + + if (!render_view()->webview()) + return; + + WebFrame* main_frame = render_view()->webview()->mainFrame(); + if (!main_frame) + return; + + // Don't index/capture pages that are in view source mode. + if (main_frame->isViewSourceModeEnabled()) + return; + + // Don't index/capture pages that failed to load. This only checks the top + // level frame so the thumbnail may contain a frame that failed to load. + WebDataSource* ds = main_frame->dataSource(); + if (ds && ds->hasUnreachableURL()) + return; + + if (!preliminary_capture) + last_indexed_page_id_ = load_id; + + // Get the URL for this page. + GURL url(main_frame->url()); + if (url.is_empty()) + return; + + // Retrieve the frame's full text. + string16 contents; + CaptureText(main_frame, &contents); + if (contents.size()) { + if (translate_helper_) + translate_helper_->PageCaptured(contents); + // 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)); + } + + // Generate the thumbnail here if the in-browser thumbnailing isn't + // enabled. TODO(satorux): Remove this and related code once + // crbug.com/65936 is complete. + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableInBrowserThumbnailing)) { + CaptureThumbnail(); + } + + // Will swap out the string. + if (phishing_classifier_) + phishing_classifier_->PageCaptured(&contents, preliminary_capture); +} + +void ChromeRenderObserver::CaptureText(WebFrame* frame, string16* contents) { + contents->clear(); + if (!frame) + return; + +#ifdef TIME_TEXT_RETRIEVAL + double begin = time_util::GetHighResolutionTimeNow(); +#endif + + // get the contents of the frame + *contents = frame->contentAsText(kMaxIndexChars); + +#ifdef TIME_TEXT_RETRIEVAL + double end = time_util::GetHighResolutionTimeNow(); + char buf[128]; + sprintf_s(buf, "%d chars retrieved for indexing in %gms\n", + contents.size(), (end - begin)*1000); + OutputDebugStringA(buf); +#endif + + // When the contents are clipped to the maximum, we don't want to have a + // partial word indexed at the end that might have been clipped. Therefore, + // terminate the string at the last space to ensure no words are clipped. + if (contents->size() == kMaxIndexChars) { + size_t last_space_index = contents->find_last_of(kWhitespaceUTF16); + if (last_space_index == std::wstring::npos) + return; // don't index if we got a huge block of text with no spaces + contents->resize(last_space_index); + } +} + +void ChromeRenderObserver::CaptureThumbnail() { + WebFrame* main_frame = render_view()->webview()->mainFrame(); + if (!main_frame) + return; + + // get the URL for this page + GURL url(main_frame->url()); + if (url.is_empty()) + return; + + if (render_view()->size().IsEmpty()) + return; // Don't create an empty thumbnail! + + ThumbnailScore score; + SkBitmap thumbnail; + if (!CaptureFrameThumbnail(render_view()->webview(), kThumbnailWidth, + kThumbnailHeight, &thumbnail, &score)) + return; + + // send the thumbnail message to the browser process + Send(new ViewHostMsg_Thumbnail(routing_id(), url, score, thumbnail)); +} + +bool ChromeRenderObserver::CaptureFrameThumbnail(WebView* view, + int w, + int h, + SkBitmap* thumbnail, + ThumbnailScore* score) { + base::TimeTicks beginning_time = base::TimeTicks::Now(); + + skia::PlatformCanvas canvas; + + // Paint |view| into |canvas|. + if (!PaintViewIntoCanvas(view, canvas)) + return false; + + skia::BitmapPlatformDevice& device = + static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice()); + + const SkBitmap& src_bmp = device.accessBitmap(false); + + SkRect dest_rect = { 0, 0, SkIntToScalar(w), SkIntToScalar(h) }; + float dest_aspect = dest_rect.width() / dest_rect.height(); + + // Get the src rect so that we can preserve the aspect ratio while filling + // the destination. + SkIRect src_rect; + if (src_bmp.width() < dest_rect.width() || + src_bmp.height() < dest_rect.height()) { + // Source image is smaller: we clip the part of source image within the + // dest rect, and then stretch it to fill the dest rect. We don't respect + // the aspect ratio in this case. + src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()), + static_cast<S16CPU>(dest_rect.height())); + score->good_clipping = false; + } else { + float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height(); + if (src_aspect > dest_aspect) { + // Wider than tall, clip horizontally: we center the smaller thumbnail in + // the wider screen. + S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect); + S16CPU x_offset = (src_bmp.width() - new_width) / 2; + src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height()); + score->good_clipping = false; + } else { + src_rect.set(0, 0, src_bmp.width(), + static_cast<S16CPU>(src_bmp.width() / dest_aspect)); + score->good_clipping = true; + } + } + + score->at_top = (view->mainFrame()->scrollOffset().height == 0); + + SkBitmap subset; + device.accessBitmap(false).extractSubset(&subset, src_rect); + + // First do a fast downsample by powers of two to get close to the final size. + SkBitmap downsampled_subset = + SkBitmapOperations::DownsampleByTwoUntilSize(subset, w, h); + + // Do a high-quality resize from the downscaled size to the final size. + *thumbnail = skia::ImageOperations::Resize( + downsampled_subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h); + + score->boring_score = CalculateBoringScore(thumbnail); + + HISTOGRAM_TIMES("Renderer4.Thumbnail", + base::TimeTicks::Now() - beginning_time); + + return true; +} + +bool ChromeRenderObserver::CaptureSnapshot(WebView* view, SkBitmap* snapshot) { + base::TimeTicks beginning_time = base::TimeTicks::Now(); + + skia::PlatformCanvas canvas; + if (!PaintViewIntoCanvas(view, canvas)) + return false; + + skia::BitmapPlatformDevice& device = + static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice()); + + const SkBitmap& bitmap = device.accessBitmap(false); + if (!bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config)) + return false; + + HISTOGRAM_TIMES("Renderer4.Snapshot", + base::TimeTicks::Now() - beginning_time); + return true; +} diff --git a/chrome/renderer/chrome_render_observer.h b/chrome/renderer/chrome_render_observer.h new file mode 100644 index 0000000..41290f2 --- /dev/null +++ b/chrome/renderer/chrome_render_observer.h @@ -0,0 +1,79 @@ +// Copyright (c) 2011 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_RENDERER_CHROME_RENDER_OBSERVER_H_ +#define CHROME_RENDERER_CHROME_RENDER_OBSERVER_H_ +#pragma once + +#include "base/task.h" +#include "content/renderer/render_view_observer.h" + +class SkBitmap; +class TranslateHelper; +struct ThumbnailScore; + +namespace WebKit { +class WebView; +} + +namespace safe_browsing { +class PhishingClassifierDelegate; +} + +// This class holds the Chrome specific parts of RenderView, and has the same +// lifetime. +class ChromeRenderObserver : public RenderViewObserver { + public: + // translate_helper and/or phishing_classifier can be NULL. + ChromeRenderObserver( + RenderView* render_view, + TranslateHelper* translate_helper, + safe_browsing::PhishingClassifierDelegate* phishing_classifier); + virtual ~ChromeRenderObserver(); + + private: + // RenderViewObserver implementation. + virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE; + virtual void DidStopLoading() OVERRIDE; + virtual void DidCommitProvisionalLoad(WebKit::WebFrame* frame, + bool is_new_navigation) OVERRIDE; + + void OnCaptureSnapshot(); + + // Captures the thumbnail and text contents for indexing for the given load + // ID. If the view's load ID is different than the parameter, this call is + // a NOP. Typically called on a timer, so the load ID may have changed in the + // meantime. + void CapturePageInfo(int load_id, bool preliminary_capture); + + // Retrieves the text from the given frame contents, the page text up to the + // maximum amount kMaxIndexChars will be placed into the given buffer. + void CaptureText(WebKit::WebFrame* frame, string16* contents); + + void CaptureThumbnail(); + + // Creates a thumbnail of |frame|'s contents resized to (|w|, |h|) + // and puts that in |thumbnail|. Thumbnail metadata goes in |score|. + bool CaptureFrameThumbnail(WebKit::WebView* view, int w, int h, + SkBitmap* thumbnail, + ThumbnailScore* score); + + // Capture a snapshot of a view. This is used to allow an extension + // to get a snapshot of a tab using chrome.tabs.captureVisibleTab(). + bool CaptureSnapshot(WebKit::WebView* view, SkBitmap* snapshot); + + // Has the same lifetime as us. + TranslateHelper* translate_helper_; + safe_browsing::PhishingClassifierDelegate* phishing_classifier_; + + // Page_id from the last page we indexed. This prevents us from indexing the + // same page twice in a row. + int32 last_indexed_page_id_; + + ScopedRunnableMethodFactory<ChromeRenderObserver> page_info_method_factory_; + + DISALLOW_COPY_AND_ASSIGN(ChromeRenderObserver); +}; + +#endif // CHROME_RENDERER_CHROME_OBSERVER_H_ diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc index d9c3174..9789920e 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate.cc @@ -138,14 +138,14 @@ void PhishingClassifierDelegate::DidCommitProvisionalLoad( CancelPendingClassification(); } -void PhishingClassifierDelegate::PageCaptured(const string16& page_text, +void PhishingClassifierDelegate::PageCaptured(string16* page_text, bool preliminary_capture) { if (preliminary_capture) { return; } last_finished_load_id_ = render_view()->page_id(); last_finished_load_url_ = GetToplevelUrl(); - classifier_page_text_ = page_text; + classifier_page_text_.swap(*page_text); MaybeStartClassification(); } diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate.h b/chrome/renderer/safe_browsing/phishing_classifier_delegate.h index 04309ba..3e3a09e 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier_delegate.h +++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate.h @@ -33,15 +33,14 @@ class PhishingClassifierDelegate : public RenderViewObserver { // The scorer is passed on to the classifier. void SetPhishingScorer(const safe_browsing::Scorer* scorer); - // RenderViewObserver implementation, public for testing. - // Called by the RenderView once a page has finished loading. Updates the // last-loaded URL and page id, then starts classification if all other // conditions are met (see MaybeStartClassification for details). // We ignore preliminary captures, since these happen before the page has // finished loading. - virtual void PageCaptured(const string16& page_text, - bool preliminary_capture); + void PageCaptured(string16* page_text, bool preliminary_capture); + + // RenderViewObserver implementation, public for testing. // Called by the RenderView when a page has started loading in the given // WebFrame. Typically, this will cause any pending classification to be diff --git a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc index 305e907..90578a4 100644 --- a/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc +++ b/chrome/renderer/safe_browsing/phishing_classifier_delegate_browsertest.cc @@ -118,7 +118,7 @@ TEST_F(PhishingClassifierDelegateTest, Navigation) { string16 page_text = ASCIIToUTF16("dummy"); EXPECT_CALL(*classifier, BeginClassification(Pointee(page_text), _)). WillOnce(DeleteArg<1>()); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); Mock::VerifyAndClearExpectations(classifier); // Reloading the same page should not trigger a reclassification. @@ -129,7 +129,8 @@ TEST_F(PhishingClassifierDelegateTest, Navigation) { message_loop_.Run(); Mock::VerifyAndClearExpectations(classifier); OnStartPhishingDetection(delegate, GURL("http://host.com/")); - delegate->PageCaptured(page_text, false); + page_text = ASCIIToUTF16("dummy"); + delegate->PageCaptured(&page_text, false); // Navigating in a subframe will increment the page id, but not change // the toplevel URL. This should cancel pending classification since the @@ -140,7 +141,8 @@ TEST_F(PhishingClassifierDelegateTest, Navigation) { message_loop_.Run(); Mock::VerifyAndClearExpectations(classifier); OnStartPhishingDetection(delegate, GURL("http://host.com/")); - delegate->PageCaptured(page_text, false); + page_text = ASCIIToUTF16("dummy"); + delegate->PageCaptured(&page_text, false); // Scrolling to an anchor will increment the page id, but should not // not trigger a reclassification. Currently, a pending classification will @@ -148,7 +150,8 @@ TEST_F(PhishingClassifierDelegateTest, Navigation) { EXPECT_CALL(*classifier, CancelPendingClassification()); LoadURL("http://host.com/#foo"); OnStartPhishingDetection(delegate, GURL("http://host.com/#foo")); - delegate->PageCaptured(page_text, false); + page_text = ASCIIToUTF16("dummy"); + delegate->PageCaptured(&page_text, false); // Now load a new toplevel page, which should trigger another classification. EXPECT_CALL(*classifier, CancelPendingClassification()); @@ -158,7 +161,7 @@ TEST_F(PhishingClassifierDelegateTest, Navigation) { EXPECT_CALL(*classifier, BeginClassification(Pointee(page_text), _)). WillOnce(DeleteArg<1>()); OnStartPhishingDetection(delegate, GURL("http://host2.com/")); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); Mock::VerifyAndClearExpectations(classifier); // No classification should happen on back/forward navigation. @@ -170,7 +173,7 @@ TEST_F(PhishingClassifierDelegateTest, Navigation) { Mock::VerifyAndClearExpectations(classifier); page_text = ASCIIToUTF16("dummy"); OnStartPhishingDetection(delegate, GURL("http://host.com/#foo")); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); // The delegate will cancel pending classification on destruction. EXPECT_CALL(*classifier, CancelPendingClassification()); @@ -188,15 +191,16 @@ TEST_F(PhishingClassifierDelegateTest, NoScorer) { LoadURL("http://host.com/"); string16 page_text = ASCIIToUTF16("dummy"); OnStartPhishingDetection(delegate, GURL("http://host.com/")); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); LoadURL("http://host2.com/"); page_text = ASCIIToUTF16("dummy2"); OnStartPhishingDetection(delegate, GURL("http://host2.com/")); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); // Now set a scorer, which should cause a classifier to be created and // the classification to proceed. + page_text = ASCIIToUTF16("dummy2"); EXPECT_CALL(*classifier, BeginClassification(Pointee(page_text), _)). WillOnce(DeleteArg<1>()); MockScorer scorer; @@ -220,14 +224,16 @@ TEST_F(PhishingClassifierDelegateTest, NoScorer_Ref) { LoadURL("http://host.com/"); string16 page_text = ASCIIToUTF16("dummy"); OnStartPhishingDetection(delegate, GURL("http://host.com/")); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); LoadURL("http://host.com/#foo"); OnStartPhishingDetection(delegate, GURL("http://host.com/#foo")); - delegate->PageCaptured(page_text, false); + page_text = ASCIIToUTF16("dummy"); + delegate->PageCaptured(&page_text, false); // Now set a scorer, which should cause a classifier to be created and // the classification to proceed. + page_text = ASCIIToUTF16("dummy"); EXPECT_CALL(*classifier, BeginClassification(Pointee(page_text), _)). WillOnce(DeleteArg<1>()); MockScorer scorer; @@ -254,9 +260,10 @@ TEST_F(PhishingClassifierDelegateTest, NoStartPhishingDetection) { LoadURL("http://host.com/"); Mock::VerifyAndClearExpectations(classifier); string16 page_text = ASCIIToUTF16("phish"); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); // Now simulate the StartPhishingDetection IPC. We expect classification // to begin. + page_text = ASCIIToUTF16("phish"); EXPECT_CALL(*classifier, BeginClassification(Pointee(page_text), _)). WillOnce(DeleteArg<1>()); OnStartPhishingDetection(delegate, GURL("http://host.com/")); @@ -267,7 +274,8 @@ TEST_F(PhishingClassifierDelegateTest, NoStartPhishingDetection) { EXPECT_CALL(*classifier, CancelPendingClassification()); responses_["http://host2.com/"] = "<html><body>phish</body></html>"; LoadURL("http://host2.com/"); - delegate->PageCaptured(page_text, false); + page_text = ASCIIToUTF16("phish"); + delegate->PageCaptured(&page_text, false); EXPECT_CALL(*classifier, CancelPendingClassification()); responses_["http://host3.com/"] = "<html><body>phish</body></html>"; @@ -295,12 +303,13 @@ TEST_F(PhishingClassifierDelegateTest, IgnorePreliminaryCapture) { Mock::VerifyAndClearExpectations(classifier); OnStartPhishingDetection(delegate, GURL("http://host.com/")); string16 page_text = ASCIIToUTF16("phish"); - delegate->PageCaptured(page_text, true); + delegate->PageCaptured(&page_text, true); // Once the non-preliminary capture happens, classification should begin. + page_text = ASCIIToUTF16("phish"); EXPECT_CALL(*classifier, BeginClassification(Pointee(page_text), _)). WillOnce(DeleteArg<1>()); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); Mock::VerifyAndClearExpectations(classifier); // The delegate will cancel pending classification on destruction. @@ -327,7 +336,7 @@ TEST_F(PhishingClassifierDelegateTest, DetectedPhishingSite) { EXPECT_CALL(*classifier, BeginClassification(Pointee(page_text), _)). WillOnce(DeleteArg<1>()); OnStartPhishingDetection(delegate, GURL("http://host.com/#a")); - delegate->PageCaptured(page_text, false); + delegate->PageCaptured(&page_text, false); Mock::VerifyAndClearExpectations(classifier); // Now run the callback to simulate the classifier finishing. diff --git a/chrome/renderer/translate_helper.cc b/chrome/renderer/translate_helper.cc index 31833b6..4d4fed1 100644 --- a/chrome/renderer/translate_helper.cc +++ b/chrome/renderer/translate_helper.cc @@ -5,14 +5,18 @@ #include "chrome/renderer/translate_helper.h" #include "base/compiler_specific.h" +#include "base/metrics/histogram.h" #include "base/utf_string_conversions.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/render_messages.h" +#include "chrome/renderer/autofill/autofill_agent.h" #include "content/renderer/render_view.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebElement.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptSource.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" +#include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h" #include "v8/include/v8.h" #include "webkit/glue/dom_operations.h" @@ -41,16 +45,34 @@ static const char* const kAutoDetectionLanguage = "auto"; //////////////////////////////////////////////////////////////////////////////// // TranslateHelper, public: // -TranslateHelper::TranslateHelper(RenderView* render_view) +TranslateHelper::TranslateHelper(RenderView* render_view, + autofill::AutofillAgent* autofill) : RenderViewObserver(render_view), translation_pending_(false), page_id_(-1), + autofill_(autofill), ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { } TranslateHelper::~TranslateHelper() { } +void TranslateHelper::PageCaptured(const string16& contents) { + WebDocument document = render_view()->webview()->mainFrame()->document(); + // If the page explicitly specifies a language, use it, otherwise we'll + // determine it based on the text content using the CLD. + std::string language = GetPageLanguageFromMetaTag(&document); + if (language.empty()) { + base::TimeTicks begin_time = base::TimeTicks::Now(); + language = DetermineTextLanguage(contents); + UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.LanguageDetection", + base::TimeTicks::Now() - begin_time); + } + + Send(new ViewHostMsg_TranslateLanguageDetermined( + routing_id(), language, IsPageTranslatable(&document))); +} + void TranslateHelper::CancelPendingTranslation() { method_factory_.RevokeAll(); translation_pending_ = false; @@ -113,6 +135,31 @@ std::string TranslateHelper::GetPageLanguageFromMetaTag(WebDocument* document) { return language; } +// static +std::string TranslateHelper::DetermineTextLanguage(const string16& text) { + std::string language = chrome::kUnknownLanguageCode; + int num_languages = 0; + int text_bytes = 0; + bool is_reliable = false; + Language cld_language = + DetectLanguageOfUnicodeText(NULL, text.c_str(), true, &is_reliable, + &num_languages, NULL, &text_bytes); + // We don't trust the result if the CLD reports that the detection is not + // reliable, or if the actual text used to detect the language was less than + // 100 bytes (short texts can often lead to wrong results). + if (is_reliable && text_bytes >= 100 && cld_language != NUM_LANGUAGES && + cld_language != UNKNOWN_LANGUAGE && cld_language != TG_UNKNOWN_LANGUAGE) { + // We should not use LanguageCode_ISO_639_1 because it does not cover all + // the languages CLD can detect. As a result, it'll return the invalid + // language code for tradtional Chinese among others. + // |LanguageCodeWithDialect| will go through ISO 639-1, ISO-639-2 and + // 'other' tables to do the 'right' thing. In addition, it'll return zh-CN + // for Simplified Chinese. + language = LanguageCodeWithDialects(cld_language); + } + return language; +} + //////////////////////////////////////////////////////////////////////////////// // TranslateHelper, protected: // @@ -284,8 +331,8 @@ void TranslateHelper::CheckTranslateStatus() { translation_pending_ = false; - // Notify the renderer we are done. - render_view()->OnPageTranslated(); + if (autofill_) + autofill_->FrameTranslated(render_view()->webview()->mainFrame()); // Notify the browser we are done. render_view()->Send(new ViewHostMsg_PageTranslated( diff --git a/chrome/renderer/translate_helper.h b/chrome/renderer/translate_helper.h index 54a4706..902f0bc 100644 --- a/chrome/renderer/translate_helper.h +++ b/chrome/renderer/translate_helper.h @@ -17,25 +17,21 @@ class WebDocument; class WebFrame; } +namespace autofill { +class AutofillAgent; +} + // This class deals with page translation. // There is one TranslateHelper per RenderView. class TranslateHelper : public RenderViewObserver { public: - explicit TranslateHelper(RenderView* render_view); + // autofill can be NULL. + TranslateHelper(RenderView* render_view, autofill::AutofillAgent* autofill); virtual ~TranslateHelper(); - // 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. - static bool IsPageTranslatable(WebKit::WebDocument* document); - - // Returns the language specified in the language meta tag of |document|, or - // an empty string if no such tag was found. - // The tag may specify several languages, the first one is returned. - // Example of such meta-tag: - // <meta http-equiv="content-language" content="en, fr"> - static std::string GetPageLanguageFromMetaTag(WebKit::WebDocument* document); + // Informs us that the page's text has been extracted. + void PageCaptured(const string16& contents); protected: // The following methods are protected so they can be overridden in @@ -75,6 +71,22 @@ class TranslateHelper : public RenderViewObserver { virtual bool DontDelayTasks(); private: + // 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. + static bool IsPageTranslatable(WebKit::WebDocument* document); + + // Returns the language specified in the language meta tag of |document|, or + // an empty string if no such tag was found. + // The tag may specify several languages, the first one is returned. + // Example of such meta-tag: + // <meta http-equiv="content-language" content="en, fr"> + static std::string GetPageLanguageFromMetaTag(WebKit::WebDocument* document); + + // Returns the ISO 639_1 language code of the specified |text|, or 'unknown' + // if it failed. + static std::string DetermineTextLanguage(const string16& text); + // RenderViewObserver implementation. virtual bool OnMessageReceived(const IPC::Message& message); @@ -123,6 +135,8 @@ class TranslateHelper : public RenderViewObserver { std::string source_lang_; std::string target_lang_; + autofill::AutofillAgent* autofill_; + // Method factory used to make calls to TranslatePageImpl. ScopedRunnableMethodFactory<TranslateHelper> method_factory_; diff --git a/chrome/renderer/translate_helper_browsertest.cc b/chrome/renderer/translate_helper_browsertest.cc index 067d939..9298305 100644 --- a/chrome/renderer/translate_helper_browsertest.cc +++ b/chrome/renderer/translate_helper_browsertest.cc @@ -15,7 +15,7 @@ using testing::Return; class TestTranslateHelper : public TranslateHelper { public: explicit TestTranslateHelper(RenderView* render_view) - : TranslateHelper(render_view) { + : TranslateHelper(render_view, NULL) { } virtual bool DontDelayTasks() { return true; } diff --git a/content/browser/tab_contents/tab_contents.cc b/content/browser/tab_contents/tab_contents.cc index 034c930..7a1e82b 100644 --- a/content/browser/tab_contents/tab_contents.cc +++ b/content/browser/tab_contents/tab_contents.cc @@ -49,7 +49,6 @@ #include "chrome/browser/tab_contents/infobar_delegate.h" #include "chrome/browser/tab_contents/tab_contents_ssl_helper.h" #include "chrome/browser/tab_contents/thumbnail_generator.h" -#include "chrome/browser/translate/page_translated_details.h" #include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h" #include "chrome/browser/ui/browser_dialogs.h" #include "chrome/common/bindings_policy.h" @@ -250,7 +249,6 @@ TabContents::TabContents(Profile* profile, suppress_javascript_messages_(false), is_showing_before_unload_dialog_(false), opener_web_ui_type_(WebUI::kNoWebUI), - language_state_(&controller_), closed_by_user_gesture_(false), minimum_zoom_percent_( static_cast<int>(WebKit::WebView::minTextSizeMultiplier * 100)), @@ -416,8 +414,6 @@ bool TabContents::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewHostMsg_PDFHasUnsupportedFeature, OnPDFHasUnsupportedFeature) IPC_MESSAGE_HANDLER(ViewHostMsg_GoToEntryAtOffset, OnGoToEntryAtOffset) - IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents) - IPC_MESSAGE_HANDLER(ViewHostMsg_PageTranslated, OnPageTranslated) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFaviconURL, OnUpdateFaviconURL) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP_EX() @@ -1587,9 +1583,6 @@ void TabContents::DidNavigateAnyFramePostCommit( // Notify observers about navigation. FOR_EACH_OBSERVER(TabContentsObserver, observers_, DidNavigateAnyFramePostCommit(details, params)); - - // Let the LanguageState clear its state. - language_state_.DidNavigate(details); } void TabContents::CloseConstrainedWindows() { @@ -1752,52 +1745,6 @@ void TabContents::OnGoToEntryAtOffset(int offset) { } } -void TabContents::OnPageContents(const GURL& url, - int32 page_id, - const string16& contents, - 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. - // TODO(brettw) we may want to consider more elaborate heuristics such as - // the cachability of the page. We may also want to consider subframes (this - // test will still index subframes if the subframe is SSL). - // TODO(zelidrag) bug chromium-os:2808 - figure out if we want to reenable - // content indexing for chromeos in some future releases. -#if !defined(OS_CHROMEOS) - if (!url.SchemeIsSecure()) { - Profile* p = profile(); - if (p && !p->IsOffTheRecord()) { - HistoryService* hs = p->GetHistoryService(Profile::IMPLICIT_ACCESS); - if (hs) - hs->SetPageContents(url, contents); - } - } -#endif - - language_state_.LanguageDetermined(language, page_translatable); - - std::string lang = language; - NotificationService::current()->Notify( - NotificationType::TAB_LANGUAGE_DETERMINED, - Source<TabContents>(this), - Details<std::string>(&lang)); -} - -void TabContents::OnPageTranslated(int32 page_id, - const std::string& original_lang, - const std::string& translated_lang, - TranslateErrors::Type error_type) { - language_state_.set_current_language(translated_lang); - language_state_.set_translation_pending(false); - PageTranslatedDetails details(original_lang, translated_lang, error_type); - NotificationService::current()->Notify( - NotificationType::PAGE_TRANSLATED, - Source<TabContents>(this), - Details<PageTranslatedDetails>(&details)); -} - void TabContents::OnContentSettingsAccessed(bool content_was_blocked) { if (delegate_) delegate_->OnContentSettingsChange(this); diff --git a/content/browser/tab_contents/tab_contents.h b/content/browser/tab_contents/tab_contents.h index a242b7d..85960f2 100644 --- a/content/browser/tab_contents/tab_contents.h +++ b/content/browser/tab_contents/tab_contents.h @@ -20,10 +20,8 @@ #include "chrome/browser/tab_contents/tab_specific_content_settings.h" #include "chrome/browser/ui/app_modal_dialogs/js_modal_dialog.h" #include "chrome/common/instant_types.h" -#include "chrome/common/translate_errors.h" #include "content/browser/renderer_host/render_view_host_delegate.h" #include "content/browser/tab_contents/constrained_window.h" -#include "content/browser/tab_contents/language_state.h" #include "content/browser/tab_contents/navigation_controller.h" #include "content/browser/tab_contents/navigation_entry.h" #include "content/browser/tab_contents/page_navigator.h" @@ -544,10 +542,6 @@ class TabContents : public PageNavigator, // times, subsequent calls are ignored. void OnCloseStarted(); - LanguageState& language_state() { - return language_state_; - } - // Returns true if underlying TabContentsView should accept drag-n-drop. bool ShouldAcceptDragAndDrop() const; @@ -698,15 +692,6 @@ class TabContents : public PageNavigator, void OnPDFHasUnsupportedFeature(); void OnGoToEntryAtOffset(int offset); - void OnPageContents(const GURL& url, - int32 page_id, - const string16& contents, - const std::string& language, - bool page_translatable); - void OnPageTranslated(int32 page_id, - const std::string& original_lang, - const std::string& translated_lang, - TranslateErrors::Type error_type); // Changes the IsLoading state and notifies delegate as needed // |details| is used to provide details on the load that just finished @@ -1093,9 +1078,6 @@ class TabContents : public PageNavigator, // The time that this tab was last selected. base::TimeTicks last_selected_time_; - // Information about the language the page is in and has been translated to. - LanguageState language_state_; - // See description above setter. bool closed_by_user_gesture_; diff --git a/content/common/view_messages.h b/content/common/view_messages.h index ae921bd..703f8c3 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -1563,14 +1563,6 @@ IPC_SYNC_MESSAGE_ROUTED4_2(ViewHostMsg_RunJavaScriptMessage, bool /* out - success */, std::wstring /* out - prompt field */) -// Provides the contents for the given page that was loaded recently. -IPC_MESSAGE_ROUTED5(ViewHostMsg_PageContents, - GURL /* URL of the page */, - int32 /* page id */, - string16 /* page contents */, - std::string /* page ISO639_1 language code */, - bool /* whether the page can be translated */) - // Requests that the given URL be opened in the specified manner. IPC_MESSAGE_ROUTED3(ViewHostMsg_OpenURL, GURL /* url */, diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 0701de2..7a90b4e 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -289,8 +289,6 @@ 'browser/tab_contents/constrained_window.h', 'browser/tab_contents/interstitial_page.cc', 'browser/tab_contents/interstitial_page.h', - 'browser/tab_contents/language_state.cc', - 'browser/tab_contents/language_state.h', 'browser/tab_contents/navigation_controller.cc', 'browser/tab_contents/navigation_controller.h', 'browser/tab_contents/navigation_entry.cc', diff --git a/content/renderer/content_renderer_client.cc b/content/renderer/content_renderer_client.cc index 79573c4..a4bdd28 100644 --- a/content/renderer/content_renderer_client.cc +++ b/content/renderer/content_renderer_client.cc @@ -33,10 +33,6 @@ std::string ContentRendererClient::GetNavigationErrorHtml( return std::string(); } -std::string ContentRendererClient::DetermineTextLanguage(const string16& text) { - return std::string(); -} - bool ContentRendererClient::RunIdleHandlerWhenWidgetsHidden() { return true; } diff --git a/content/renderer/content_renderer_client.h b/content/renderer/content_renderer_client.h index e9bcbf9..ea15759 100644 --- a/content/renderer/content_renderer_client.h +++ b/content/renderer/content_renderer_client.h @@ -49,10 +49,6 @@ class ContentRendererClient { const WebKit::WebURLRequest& failed_request, const WebKit::WebURLError& error); - // Returns the ISO 639_1 language code of the specified |text|, or 'unknown' - // if it failed. - virtual std::string DetermineTextLanguage(const string16& text); - // Returns true if the renderer process should schedule the idle handler when // all widgets are hidden. virtual bool RunIdleHandlerWhenWidgetsHidden(); diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc index 44027a0..83d6756 100644 --- a/content/renderer/render_view.cc +++ b/content/renderer/render_view.cc @@ -32,7 +32,6 @@ #include "chrome/common/pepper_plugin_registry.h" #include "chrome/common/render_messages.h" #include "chrome/common/render_view_commands.h" -#include "chrome/common/thumbnail_score.h" #include "chrome/common/url_constants.h" #include "chrome/common/web_apps.h" #include "chrome/renderer/about_handler.h" @@ -45,7 +44,6 @@ #include "chrome/renderer/searchbox.h" #include "chrome/renderer/spellchecker/spellcheck.h" #include "chrome/renderer/spellchecker/spellcheck_provider.h" -#include "chrome/renderer/translate_helper.h" #include "chrome/renderer/visitedlink_slave.h" #include "content/common/appcache/appcache_dispatcher.h" #include "content/common/clipboard_messages.h" @@ -89,8 +87,6 @@ #include "net/base/net_errors.h" #include "net/http/http_util.h" #include "ppapi/c/private/ppb_flash_net_connector.h" -#include "skia/ext/bitmap_platform_device.h" -#include "skia/ext/image_operations.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityCache.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebAccessibilityObject.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h" @@ -135,12 +131,10 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebWindowFeatures.h" #include "third_party/skia/include/core/SkBitmap.h" #include "ui/base/message_box_flags.h" -#include "ui/gfx/color_utils.h" #include "ui/gfx/favicon_size.h" #include "ui/gfx/native_widget_types.h" #include "ui/gfx/point.h" #include "ui/gfx/rect.h" -#include "ui/gfx/skbitmap_operations.h" #include "v8/include/v8-testing.h" #include "v8/include/v8.h" #include "webkit/appcache/web_application_cache_host_impl.h" @@ -265,28 +259,6 @@ using webkit_glue::WebAccessibility; typedef std::map<WebKit::WebView*, RenderView*> ViewMap; static base::LazyInstance<ViewMap> g_view_map(base::LINKER_INITIALIZED); -// define to write the time necessary for thumbnail/DOM text retrieval, -// respectively, into the system debug log -// #define TIME_TEXT_RETRIEVAL - -// maximum number of characters in the document to index, any text beyond this -// point will be clipped -static const size_t kMaxIndexChars = 65535; - -// Size of the thumbnails that we'll generate -static const int kThumbnailWidth = 212; -static const int kThumbnailHeight = 132; - -// Delay in milliseconds that we'll wait before capturing the page contents -// and thumbnail. -static const int kDelayForCaptureMs = 500; - -// Typically, we capture the page data once the page is loaded. -// Sometimes, the page never finishes to load, preventing the page capture -// To workaround this problem, we always perform a capture after the following -// delay. -static const int kDelayForForcedCaptureMs = 6000; - // Time, in seconds, we delay before sending content state changes (such as form // state and scroll position) to the browser. We delay sending changes to avoid // spamming the browser. @@ -311,35 +283,6 @@ static void GetRedirectChain(WebDataSource* ds, std::vector<GURL>* result) { result->push_back(urls[i]); } -static bool PaintViewIntoCanvas(WebView* view, - skia::PlatformCanvas& canvas) { - view->layout(); - const WebSize& size = view->size(); - - if (!canvas.initialize(size.width, size.height, true)) - return false; - - view->paint(webkit_glue::ToWebCanvas(&canvas), - WebRect(0, 0, size.width, size.height)); - // TODO: Add a way to snapshot the whole page, not just the currently - // visible part. - - return true; -} - -// Calculates how "boring" a thumbnail is. The boring score is the -// 0,1 ranged percentage of pixels that are the most common -// luma. Higher boring scores indicate that a higher percentage of a -// bitmap are all the same brightness. -static double CalculateBoringScore(SkBitmap* bitmap) { - int histogram[256] = {0}; - color_utils::BuildLumaHistogram(bitmap, histogram); - - int color_count = *std::max_element(histogram, histogram + 256); - int pixel_count = bitmap->width() * bitmap->height(); - return static_cast<double>(color_count) / pixel_count; -} - // True if |frame| contains content that is white-listed for content settings. static bool IsWhitelistedForContentSettings(WebFrame* frame) { WebSecurityOrigin origin = frame->securityOrigin(); @@ -482,7 +425,6 @@ RenderView::RenderView(RenderThreadBase* render_thread, is_prerendering_(false), page_id_(-1), last_page_id_sent_to_browser_(-1), - last_indexed_page_id_(-1), history_list_offset_(-1), history_list_length_(0), has_unload_listener_(false), @@ -490,7 +432,6 @@ RenderView::RenderView(RenderThreadBase* render_thread, view_type_(ViewType::INVALID), browser_window_id_(-1), ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)), - ALLOW_THIS_IN_INITIALIZER_LIST(page_info_method_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(accessibility_method_factory_(this)), ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)), geolocation_dispatcher_(NULL), @@ -884,7 +825,6 @@ bool RenderView::OnMessageReceived(const IPC::Message& message) { bool handled = true; IPC_BEGIN_MESSAGE_MAP(RenderView, message) - IPC_MESSAGE_HANDLER(ViewMsg_CaptureSnapshot, OnCaptureSnapshot) IPC_MESSAGE_HANDLER(ViewMsg_Navigate, OnNavigate) IPC_MESSAGE_HANDLER(ViewMsg_Stop, OnStop) IPC_MESSAGE_HANDLER(ViewMsg_ReloadFrame, OnReloadFrame) @@ -1004,232 +944,6 @@ bool RenderView::OnMessageReceived(const IPC::Message& message) { return handled; } -void RenderView::OnCaptureThumbnail() { - WebFrame* main_frame = webview()->mainFrame(); - if (!main_frame) - return; - - // get the URL for this page - GURL url(main_frame->url()); - if (url.is_empty()) - return; - - if (size_.IsEmpty()) - return; // Don't create an empty thumbnail! - - ThumbnailScore score; - SkBitmap thumbnail; - if (!CaptureThumbnail(webview(), kThumbnailWidth, kThumbnailHeight, - &thumbnail, &score)) - return; - - // send the thumbnail message to the browser process - Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail)); -} - -void RenderView::OnCaptureSnapshot() { - SkBitmap snapshot; - bool error = false; - - WebFrame* main_frame = webview()->mainFrame(); - if (!main_frame) - error = true; - - if (!error && !CaptureSnapshot(webview(), &snapshot)) - error = true; - - DCHECK(error == snapshot.empty()) << - "Snapshot should be empty on error, non-empty otherwise."; - - // Send the snapshot to the browser process. - Send(new ViewHostMsg_Snapshot(routing_id_, snapshot)); -} - -void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) { - if (load_id != page_id_) - return; // this capture call is no longer relevant due to navigation - if (load_id == last_indexed_page_id_) - return; // we already indexed this page - - if (!webview()) - return; - - WebFrame* main_frame = webview()->mainFrame(); - if (!main_frame) - return; - - // Don't index/capture pages that are in view source mode. - if (main_frame->isViewSourceModeEnabled()) - return; - - // Don't index/capture pages that failed to load. This only checks the top - // level frame so the thumbnail may contain a frame that failed to load. - WebDataSource* ds = main_frame->dataSource(); - if (ds && ds->hasUnreachableURL()) - return; - - if (!preliminary_capture) - last_indexed_page_id_ = load_id; - - // Get the URL for this page. - GURL url(main_frame->url()); - if (url.is_empty()) - return; - - // Retrieve the frame's full text. - string16 contents; - CaptureText(main_frame, &contents); - if (contents.size()) { - WebKit::WebDocument document = main_frame->document(); - // If the page explicitly specifies a language, use it, otherwise we'll - // determine it based on the text content using the CLD. - std::string language = - TranslateHelper::GetPageLanguageFromMetaTag(&document); - if (language.empty()) { - base::TimeTicks begin_time = base::TimeTicks::Now(); - language = content::GetContentClient()->renderer()-> - DetermineTextLanguage(contents); - UMA_HISTOGRAM_MEDIUM_TIMES("Renderer4.LanguageDetection", - base::TimeTicks::Now() - begin_time); - } - // 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, - TranslateHelper::IsPageTranslatable(&document))); - } - - // Generate the thumbnail here if the in-browser thumbnailing isn't - // enabled. TODO(satorux): Remove this and related code once - // crbug.com/65936 is complete. - if (!CommandLine::ForCurrentProcess()->HasSwitch( - switches::kEnableInBrowserThumbnailing)) { - OnCaptureThumbnail(); - } - - FOR_EACH_OBSERVER(RenderViewObserver, observers_, - PageCaptured(contents, preliminary_capture)); -} - -void RenderView::CaptureText(WebFrame* frame, string16* contents) { - contents->clear(); - if (!frame) - return; - -#ifdef TIME_TEXT_RETRIEVAL - double begin = time_util::GetHighResolutionTimeNow(); -#endif - - // get the contents of the frame - *contents = frame->contentAsText(kMaxIndexChars); - -#ifdef TIME_TEXT_RETRIEVAL - double end = time_util::GetHighResolutionTimeNow(); - char buf[128]; - sprintf_s(buf, "%d chars retrieved for indexing in %gms\n", - contents.size(), (end - begin)*1000); - OutputDebugStringA(buf); -#endif - - // When the contents are clipped to the maximum, we don't want to have a - // partial word indexed at the end that might have been clipped. Therefore, - // terminate the string at the last space to ensure no words are clipped. - if (contents->size() == kMaxIndexChars) { - size_t last_space_index = contents->find_last_of(kWhitespaceUTF16); - if (last_space_index == std::wstring::npos) - return; // don't index if we got a huge block of text with no spaces - contents->resize(last_space_index); - } -} - -bool RenderView::CaptureThumbnail(WebView* view, - int w, - int h, - SkBitmap* thumbnail, - ThumbnailScore* score) { - base::TimeTicks beginning_time = base::TimeTicks::Now(); - - skia::PlatformCanvas canvas; - - // Paint |view| into |canvas|. - if (!PaintViewIntoCanvas(view, canvas)) - return false; - - skia::BitmapPlatformDevice& device = - static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice()); - - const SkBitmap& src_bmp = device.accessBitmap(false); - - SkRect dest_rect = { 0, 0, SkIntToScalar(w), SkIntToScalar(h) }; - float dest_aspect = dest_rect.width() / dest_rect.height(); - - // Get the src rect so that we can preserve the aspect ratio while filling - // the destination. - SkIRect src_rect; - if (src_bmp.width() < dest_rect.width() || - src_bmp.height() < dest_rect.height()) { - // Source image is smaller: we clip the part of source image within the - // dest rect, and then stretch it to fill the dest rect. We don't respect - // the aspect ratio in this case. - src_rect.set(0, 0, static_cast<S16CPU>(dest_rect.width()), - static_cast<S16CPU>(dest_rect.height())); - score->good_clipping = false; - } else { - float src_aspect = static_cast<float>(src_bmp.width()) / src_bmp.height(); - if (src_aspect > dest_aspect) { - // Wider than tall, clip horizontally: we center the smaller thumbnail in - // the wider screen. - S16CPU new_width = static_cast<S16CPU>(src_bmp.height() * dest_aspect); - S16CPU x_offset = (src_bmp.width() - new_width) / 2; - src_rect.set(x_offset, 0, new_width + x_offset, src_bmp.height()); - score->good_clipping = false; - } else { - src_rect.set(0, 0, src_bmp.width(), - static_cast<S16CPU>(src_bmp.width() / dest_aspect)); - score->good_clipping = true; - } - } - - score->at_top = (view->mainFrame()->scrollOffset().height == 0); - - SkBitmap subset; - device.accessBitmap(false).extractSubset(&subset, src_rect); - - // First do a fast downsample by powers of two to get close to the final size. - SkBitmap downsampled_subset = - SkBitmapOperations::DownsampleByTwoUntilSize(subset, w, h); - - // Do a high-quality resize from the downscaled size to the final size. - *thumbnail = skia::ImageOperations::Resize( - downsampled_subset, skia::ImageOperations::RESIZE_LANCZOS3, w, h); - - score->boring_score = CalculateBoringScore(thumbnail); - - HISTOGRAM_TIMES("Renderer4.Thumbnail", - base::TimeTicks::Now() - beginning_time); - - return true; -} - -bool RenderView::CaptureSnapshot(WebView* view, SkBitmap* snapshot) { - base::TimeTicks beginning_time = base::TimeTicks::Now(); - - skia::PlatformCanvas canvas; - if (!PaintViewIntoCanvas(view, canvas)) - return false; - - skia::BitmapPlatformDevice& device = - static_cast<skia::BitmapPlatformDevice&>(canvas.getTopPlatformDevice()); - - const SkBitmap& bitmap = device.accessBitmap(false); - if (!bitmap.copyTo(snapshot, SkBitmap::kARGB_8888_Config)) - return false; - - HISTOGRAM_TIMES("Renderer4.Snapshot", - base::TimeTicks::Now() - beginning_time); - return true; -} - void RenderView::OnNavigate(const ViewMsg_Navigate_Params& params) { if (!webview()) return; @@ -1997,6 +1711,8 @@ void RenderView::didStartLoading() { first_default_plugin_.reset(); Send(new ViewHostMsg_DidStartLoading(routing_id_)); + + FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStartLoading()); } void RenderView::didStopLoading() { @@ -2029,11 +1745,7 @@ void RenderView::didStopLoading() { if (load_progress_tracker_ != NULL) load_progress_tracker_->DidStopLoading(); - MessageLoop::current()->PostDelayedTask( - FROM_HERE, - page_info_method_factory_.NewRunnableMethod( - &RenderView::CapturePageInfo, page_id_, false), - send_content_state_immediately_ ? 0 : kDelayForCaptureMs); + FOR_EACH_OBSERVER(RenderViewObserver, observers_, DidStopLoading()); } void RenderView::didChangeLoadProgress(WebFrame* frame, double load_progress) { @@ -3081,12 +2793,6 @@ void RenderView::didCommitProvisionalLoad(WebFrame* frame, if (history_list_offset_ >= chrome::kMaxSessionHistoryEntries) history_list_offset_ = chrome::kMaxSessionHistoryEntries - 1; history_list_length_ = history_list_offset_ + 1; - - MessageLoop::current()->PostDelayedTask( - FROM_HERE, - page_info_method_factory_.NewRunnableMethod( - &RenderView::CapturePageInfo, page_id_, true), - kDelayForForcedCaptureMs); } else { // Inspect the navigation_state on this frame to see if the navigation // corresponds to a session history navigation... Note: |frame| may or @@ -4939,14 +4645,6 @@ bool RenderView::ScheduleFileChooser( return true; } -void RenderView::OnPageTranslated() { - WebFrame* frame = webview()->mainFrame(); - if (!frame) - return; - - FOR_EACH_OBSERVER(RenderViewObserver, observers_, FrameTranslated(frame)); -} - WebKit::WebGeolocationClient* RenderView::geolocationClient() { if (!geolocation_dispatcher_) geolocation_dispatcher_ = new GeolocationDispatcher(this); diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h index 6542966..747ac35 100644 --- a/content/renderer/render_view.h +++ b/content/renderer/render_view.h @@ -78,7 +78,6 @@ class WebPluginDelegateProxy; class WebUIBindings; struct ContextMenuMediaParams; struct PP_Flash_NetAddress; -struct ThumbnailScore; struct ViewHostMsg_RunFileChooser_Params; struct ViewMsg_ClosePage_Params; struct ViewMsg_Navigate_Params; @@ -228,6 +227,7 @@ class RenderView : public RenderWidget, return webkit_preferences_; } + bool content_state_immediately() { return send_content_state_immediately_; } void set_send_content_state_immediately(bool value) { send_content_state_immediately_ = value; } @@ -276,10 +276,6 @@ class RenderView : public RenderWidget, bool ScheduleFileChooser(const ViewHostMsg_RunFileChooser_Params& params, WebKit::WebFileChooserCompletion* completion); - // Called when the translate helper has finished translating the page. We - // use this signal to re-scan the page for forms. - void OnPageTranslated(); - // Sets the content settings that back allowScripts(), allowImages(), and // allowPlugins(). void SetContentSettings(const ContentSettings& settings); @@ -710,26 +706,6 @@ class RenderView : public RenderWidget, void OpenURL(const GURL& url, const GURL& referrer, WebKit::WebNavigationPolicy policy); - // Captures the thumbnail and text contents for indexing for the given load - // ID. If the view's load ID is different than the parameter, this call is - // a NOP. Typically called on a timer, so the load ID may have changed in the - // meantime. - void CapturePageInfo(int load_id, bool preliminary_capture); - - // Retrieves the text from the given frame contents, the page text up to the - // maximum amount kMaxIndexChars will be placed into the given buffer. - void CaptureText(WebKit::WebFrame* frame, string16* contents); - - // Creates a thumbnail of |frame|'s contents resized to (|w|, |h|) - // and puts that in |thumbnail|. Thumbnail metadata goes in |score|. - bool CaptureThumbnail(WebKit::WebView* view, int w, int h, - SkBitmap* thumbnail, - ThumbnailScore* score); - - // Capture a snapshot of a view. This is used to allow an extension - // to get a snapshot of a tab using chrome.tabs.captureVisibleTab(). - bool CaptureSnapshot(WebKit::WebView* view, SkBitmap* snapshot); - bool RunJavaScriptMessage(int type, const std::wstring& message, const std::wstring& default_value, @@ -776,8 +752,6 @@ class RenderView : public RenderWidget, void OnCopyToFindPboard(); #endif void OnCut(); - void OnCaptureThumbnail(); - void OnCaptureSnapshot(); void OnCSSInsertRequest(const std::wstring& frame_xpath, const std::string& css, const std::string& id); @@ -1117,10 +1091,6 @@ class RenderView : public RenderWidget, // goes back. int32 last_page_id_sent_to_browser_; - // Page_id from the last page we indexed. This prevents us from indexing the - // same page twice in a row. - int32 last_indexed_page_id_; - // The next available page ID to use. This ensures that the page IDs are // globally unique in the renderer. static int32 next_page_id_; @@ -1210,7 +1180,6 @@ class RenderView : public RenderWidget, // Helper objects ------------------------------------------------------------ - ScopedRunnableMethodFactory<RenderView> page_info_method_factory_; ScopedRunnableMethodFactory<RenderView> accessibility_method_factory_; RendererWebCookieJarImpl cookie_jar_; diff --git a/content/renderer/render_view_browsertest.cc b/content/renderer/render_view_browsertest.cc index c9a9e4a..f64c0df 100644 --- a/content/renderer/render_view_browsertest.cc +++ b/content/renderer/render_view_browsertest.cc @@ -1179,11 +1179,11 @@ TEST_F(RenderViewTest, TranslatablePage) { LoadHTML("<html><body>A random page with random content.</body></html>"); ProcessPendingMessages(); const IPC::Message* message = render_thread_.sink().GetUniqueMessageMatching( - ViewHostMsg_PageContents::ID); + ViewHostMsg_TranslateLanguageDetermined::ID); ASSERT_NE(static_cast<IPC::Message*>(NULL), message); - ViewHostMsg_PageContents::Param params; - ViewHostMsg_PageContents::Read(message, ¶ms); - EXPECT_TRUE(params.e); // Translatable should be true. + ViewHostMsg_TranslateLanguageDetermined::Param params; + ViewHostMsg_TranslateLanguageDetermined::Read(message, ¶ms); + EXPECT_TRUE(params.b); // Translatable should be true. render_thread_.sink().ClearMessages(); // Now the page specifies the META tag to prevent translation. @@ -1191,10 +1191,10 @@ TEST_F(RenderViewTest, TranslatablePage) { "<body>A random page with random content.</body></html>"); ProcessPendingMessages(); message = render_thread_.sink().GetUniqueMessageMatching( - ViewHostMsg_PageContents::ID); + ViewHostMsg_TranslateLanguageDetermined::ID); ASSERT_NE(static_cast<IPC::Message*>(NULL), message); - ViewHostMsg_PageContents::Read(message, ¶ms); - EXPECT_FALSE(params.e); // Translatable should be false. + ViewHostMsg_TranslateLanguageDetermined::Read(message, ¶ms); + EXPECT_FALSE(params.b); // Translatable should be false. render_thread_.sink().ClearMessages(); // Try the alternate version of the META tag (content instead of value). @@ -1202,10 +1202,10 @@ TEST_F(RenderViewTest, TranslatablePage) { "<body>A random page with random content.</body></html>"); ProcessPendingMessages(); message = render_thread_.sink().GetUniqueMessageMatching( - ViewHostMsg_PageContents::ID); + ViewHostMsg_TranslateLanguageDetermined::ID); ASSERT_NE(static_cast<IPC::Message*>(NULL), message); - ViewHostMsg_PageContents::Read(message, ¶ms); - EXPECT_FALSE(params.e); // Translatable should be false. + ViewHostMsg_TranslateLanguageDetermined::Read(message, ¶ms); + EXPECT_FALSE(params.b); // Translatable should be false. } // Tests that the language meta tag takes precedence over the CLD when reporting @@ -1219,11 +1219,11 @@ TEST_F(RenderViewTest, LanguageMetaTag) { "</head><body>A random page with random content.</body></html>"); ProcessPendingMessages(); const IPC::Message* message = render_thread_.sink().GetUniqueMessageMatching( - ViewHostMsg_PageContents::ID); + ViewHostMsg_TranslateLanguageDetermined::ID); ASSERT_NE(static_cast<IPC::Message*>(NULL), message); - ViewHostMsg_PageContents::Param params; - ViewHostMsg_PageContents::Read(message, ¶ms); - EXPECT_EQ("es", params.d); + ViewHostMsg_TranslateLanguageDetermined::Param params; + ViewHostMsg_TranslateLanguageDetermined::Read(message, ¶ms); + EXPECT_EQ("es", params.a); render_thread_.sink().ClearMessages(); // Makes sure we support multiple languages specified. @@ -1232,8 +1232,8 @@ TEST_F(RenderViewTest, LanguageMetaTag) { "</head><body>A random page with random content.</body></html>"); ProcessPendingMessages(); message = render_thread_.sink().GetUniqueMessageMatching( - ViewHostMsg_PageContents::ID); + ViewHostMsg_TranslateLanguageDetermined::ID); ASSERT_NE(static_cast<IPC::Message*>(NULL), message); - ViewHostMsg_PageContents::Read(message, ¶ms); - EXPECT_EQ("fr", params.d); + ViewHostMsg_TranslateLanguageDetermined::Read(message, ¶ms); + EXPECT_EQ("fr", params.a); } diff --git a/content/renderer/render_view_observer.h b/content/renderer/render_view_observer.h index 8ccac5a..9a49bdc 100644 --- a/content/renderer/render_view_observer.h +++ b/content/renderer/render_view_observer.h @@ -29,7 +29,9 @@ class RenderViewObserver : public IPC::Channel::Listener, // they want to outlive it, they can override this function. virtual void OnDestruct(); - // These match the WebKit API notifications. + // These match the WebKit API notifications + virtual void DidStartLoading() {} + virtual void DidStopLoading() {} virtual void DidFinishDocumentLoad(WebKit::WebFrame* frame) {} virtual void DidFailLoad(WebKit::WebFrame* frame, const WebKit::WebURLError& error) {} @@ -55,10 +57,7 @@ class RenderViewObserver : public IPC::Channel::Listener, virtual void PrintPage(WebKit::WebFrame* frame) {} // These match the RenderView methods below. - virtual void FrameTranslated(WebKit::WebFrame* frame) {} virtual void DidHandleMouseEvent(const WebKit::WebMouseEvent& event) {} - virtual void PageCaptured(const string16& page_text, - bool preliminary_capture) {} protected: explicit RenderViewObserver(RenderView* render_view); diff --git a/content/renderer/render_widget.h b/content/renderer/render_widget.h index decdc69..a3ce7b0 100644 --- a/content/renderer/render_widget.h +++ b/content/renderer/render_widget.h @@ -81,14 +81,9 @@ class RenderWidget : public IPC::Channel::Listener, } // May return NULL when the window is closing. - WebKit::WebWidget* webwidget() const { - return webwidget_; - } - - gfx::NativeViewId host_window() const { - return host_window_; - } - + WebKit::WebWidget* webwidget() const { return webwidget_; } + gfx::NativeViewId host_window() const { return host_window_; } + gfx::Size size() const { return size_; } bool has_focus() const { return has_focus_; } // IPC::Channel::Listener |