diff options
23 files changed, 339 insertions, 128 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc index c2a76a6..0868c7b 100644 --- a/chrome/browser/browser.cc +++ b/chrome/browser/browser.cc @@ -1189,8 +1189,8 @@ void Browser::OpenCreateShortcutsDialog() { DCHECK(pending_web_app_action_ == NONE); pending_web_app_action_ = CREATE_SHORTCUT; - // Start fetching web app info for CreateApplicatoinShortcut dialog and - // show the dialog when the data is available in OnDidGetApplicationInfo. + // Start fetching web app info for CreateApplicationShortcut dialog and show + // the dialog when the data is available in OnDidGetApplicationInfo. current_tab->render_view_host()->GetApplicationInfo(entry->page_id()); #else NOTIMPLEMENTED(); diff --git a/chrome/browser/browser_browsertest.cc b/chrome/browser/browser_browsertest.cc index 756b7dc..a948947 100644 --- a/chrome/browser/browser_browsertest.cc +++ b/chrome/browser/browser_browsertest.cc @@ -288,3 +288,36 @@ IN_PROC_BROWSER_TEST_F(BrowserTest, FaviconOfOnloadRedirectToAnchorPage) { controller().GetActiveEntry(); EXPECT_EQ(expected_favicon_url.spec(), entry->favicon().url().spec()); } + +// The CLD library only works on Windows at this point. +#if defined(OS_WIN) +// Tests that the CLD (Compact Language Detection) works properly. +IN_PROC_BROWSER_TEST_F(BrowserTest, PageLanguageDetection) { + static const wchar_t kDocRoot[] = L"chrome/test/data"; + scoped_refptr<HTTPTestServer> server( + HTTPTestServer::CreateServer(kDocRoot, NULL)); + ASSERT_TRUE(NULL != server.get()); + + TabContents* current_tab = browser()->GetSelectedTabContents(); + + // Navigate to a page in English. + ui_test_utils::NavigateToURL( + browser(), GURL(server->TestServerPage("files/english_page.html"))); + NavigationEntry* entry = current_tab->controller().GetActiveEntry(); + ASSERT_TRUE(NULL != entry); + EXPECT_TRUE(entry->language().empty()); + std::string lang = ui_test_utils::WaitForLanguageDetection(current_tab); + EXPECT_EQ("en", lang); + EXPECT_EQ("en", entry->language()); + + // Now navigate to a page in French. + ui_test_utils::NavigateToURL( + browser(), GURL(server->TestServerPage("files/french_page.html"))); + entry = current_tab->controller().GetActiveEntry(); + ASSERT_TRUE(NULL != entry); + EXPECT_TRUE(entry->language().empty()); + lang = ui_test_utils::WaitForLanguageDetection(current_tab); + EXPECT_EQ("fr", lang); + EXPECT_EQ("fr", entry->language()); +} +#endif diff --git a/chrome/browser/cld_helper.cc b/chrome/browser/cld_helper.cc new file mode 100644 index 0000000..f38a6a2 --- /dev/null +++ b/chrome/browser/cld_helper.cc @@ -0,0 +1,64 @@ +// Copyright (c) 2009 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/cld_helper.h" + +#include "chrome/browser/chrome_thread.h" +#include "chrome/browser/renderer_host/render_view_host.h" +#include "chrome/common/notification_service.h" + +#if defined(OS_WIN) +// TODO(port): The compact language detection library works only for Windows. +#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/win/cld_unicodetext.h" +#endif + +CLDHelper::CLDHelper(int process_id, int routing_id, int page_id, + const std::wstring& page_content) + : process_id_(process_id), + routing_id_(routing_id), + page_id_(page_id), + page_content_(page_content) { +} + +void CLDHelper::DetectLanguage() { + // Balanced in DetectionDone. + AddRef(); + + // Do the actual work on the file thread. + ChromeThread::PostTask(ChromeThread::FILE, FROM_HERE, + NewRunnableMethod(this, &CLDHelper::DoDetectLanguage)); +} + +void CLDHelper::DoDetectLanguage() { +#if defined(OS_WIN) // Only for windows. + int num_languages = 0; + bool is_reliable = false; + const char* language_iso_code = LanguageCodeISO639_1( + DetectLanguageOfUnicodeText(page_content_.c_str(), true, &is_reliable, + &num_languages, NULL)); + language_ = language_iso_code; +#else + // TODO(jcampan): port the compact language detection library. + NOTIMPLEMENTED(); +#endif + + // Work is done, notify the RenderViewHost on the UI thread. + ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, + NewRunnableMethod(this, &CLDHelper::DetectionDone)); +} + +void CLDHelper::DetectionDone() { + RenderViewHost* rvh = RenderViewHost::FromID(process_id_, routing_id_); + // The RenderViewHost might be gone (tab closed for example) while we were + // performing the detection. + if (rvh) { + NotificationService::current()->Notify( + NotificationType::TAB_LANGUAGE_DETERMINED, + Source<RenderViewHost>(rvh), + Details<std::string>(&language_)); + } + + // Remove the ref we added to ourself in DetectLanguage(). + Release(); +} diff --git a/chrome/browser/cld_helper.h b/chrome/browser/cld_helper.h new file mode 100644 index 0000000..0251145 --- /dev/null +++ b/chrome/browser/cld_helper.h @@ -0,0 +1,61 @@ +// Copyright (c) 2009 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_CLD_HELPER_H_ +#define CHROME_BROWSER_CLD_HELPER_H_ + +#include <string> + +#include "base/ref_counted.h" + +// The CLDHelper class detects the language of a page, using the toolbar CLD +// detection library. (CLD stands for Compact Language Detection.) +// It should be created and the detection process started on the same thread. +// The detection happens on the file thread and a TAB_LANGUAGE_DETERMINED +// notification is sent (on the UI thread) when the language has been detected. +class CLDHelper : public base::RefCountedThreadSafe<CLDHelper> { + public: + // |process_id| and |routing_id| should reference the RenderViewHost this page + // is related to. |page_id| is the id of the page for the specified + // |page_contents|. + CLDHelper(int process_id, + int routing_id, + int page_id, + const std::wstring& page_content); + + // Starts the process of detecting the language of the page. + void DetectLanguage(); + + int page_id() const { return page_id_; } + + std::string language() const { return language_; } + + private: + // Private because the class is ref counted. + friend class base::RefCountedThreadSafe<CLDHelper>; + ~CLDHelper() {} + + // Performs the actual work of detecting the language. + void DoDetectLanguage(); + + // Invoked on the UI thread once the language has been detected. + void DetectionDone(); + + // The process id and routing id of the RenderViewHost for which the language + // is being detected. + int process_id_; + int routing_id_; + + // The id and content of the page for which the language is being detected. + int page_id_; + std::wstring page_content_; + + // The language that was detected. + std::string language_; + + DISALLOW_COPY_AND_ASSIGN(CLDHelper); +}; + +#endif // CHROME_BROWSER_CLD_HELPER_H_ + diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index 64ee348..a97e098 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -839,15 +839,24 @@ bool DetectTabLanguageFunction::RunImpl() { return false; } - // Figure out what language |contents| contains. This sends an async call via - // the browser to the renderer to determine the language of the tab the - // renderer has. The renderer sends back the language of the tab after the - // tab loads (it may be delayed) to the browser, which in turn notifies this - // object that the language has been received. - contents->GetPageLanguage(); + AddRef(); // Balanced in GotLanguage() + + NavigationEntry* entry = contents->controller().GetActiveEntry(); + if (entry) { + std::string language = entry->language(); + if (!language.empty()) { + // Delay the callback invocation until after the current JS call has + // returned. + MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod( + this, &DetectTabLanguageFunction::GotLanguage, language)); + return true; + } + } + // The tab contents does not know its language yet. Let's wait until it + // receives it. registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, - NotificationService::AllSources()); - AddRef(); // balanced in Observe() + Source<RenderViewHost>(contents->render_view_host())); + return true; } @@ -856,9 +865,16 @@ void DetectTabLanguageFunction::Observe(NotificationType type, const NotificationDetails& details) { DCHECK(type == NotificationType::TAB_LANGUAGE_DETERMINED); std::string language(*Details<std::string>(details).ptr()); + registrar_.Remove(this, NotificationType::TAB_LANGUAGE_DETERMINED, source); + + GotLanguage(language); +} + +void DetectTabLanguageFunction::GotLanguage(const std::string& language) { result_.reset(Value::CreateStringValue(language.c_str())); SendResponse(true); - Release(); // balanced in Run() + + Release(); // Balanced in Run() } // static helpers diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h index 1fa7f21..4a0ec45 100644 --- a/chrome/browser/extensions/extension_tabs_module.h +++ b/chrome/browser/extensions/extension_tabs_module.h @@ -131,6 +131,7 @@ class DetectTabLanguageFunction : public AsyncExtensionFunction, virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); + void GotLanguage(const std::string& language); NotificationRegistrar registrar_; DECLARE_EXTENSION_FUNCTION_NAME("tabs.detectLanguage") }; diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index bb7e99d..c164fb8 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -733,10 +733,9 @@ bool BrowserRenderProcessHost::Send(IPC::Message* msg) { void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) { mark_child_process_activity_time(); if (msg.routing_id() == MSG_ROUTING_CONTROL) { - // dispatch control messages + // Dispatch control messages. bool msg_is_ok = true; IPC_BEGIN_MESSAGE_MAP_EX(BrowserRenderProcessHost, msg, msg_is_ok) - IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdatedCacheStats, OnUpdatedCacheStats) IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged, @@ -760,7 +759,7 @@ void BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) { return; } - // dispatch incoming messages to the appropriate TabContents + // Dispatch incoming messages to the appropriate TabContents. IPC::Channel::Listener* listener = GetListenerByID(msg.routing_id()); if (!listener) { if (msg.is_sync()) { @@ -834,18 +833,6 @@ void BrowserRenderProcessHost::OnChannelError() { // TODO(darin): clean this up } -void BrowserRenderProcessHost::OnPageContents(const GURL& url, - int32 page_id, - const std::wstring& contents) { - Profile* p = profile(); - if (!p || p->IsOffTheRecord()) - return; - - HistoryService* hs = p->GetHistoryService(Profile::IMPLICIT_ACCESS); - if (hs) - hs->SetPageContents(url, contents); -} - void BrowserRenderProcessHost::OnUpdatedCacheStats( const WebCache::UsageStats& stats) { WebCacheManager::GetInstance()->ObserveStats(id(), stats); diff --git a/chrome/browser/renderer_host/browser_render_process_host.h b/chrome/browser/renderer_host/browser_render_process_host.h index cd94bf5..a5c536d 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.h +++ b/chrome/browser/renderer_host/browser_render_process_host.h @@ -104,8 +104,6 @@ class BrowserRenderProcessHost : public RenderProcessHost, friend class VisitRelayingRenderProcessHost; // Control message handlers. - void OnPageContents(const GURL& url, int32 page_id, - const std::wstring& contents); void OnUpdatedCacheStats(const WebKit::WebCache::UsageStats& stats); void SuddenTerminationChanged(bool enabled); void OnExtensionAddListener(const std::string& event_name); diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index d67fda3..136ad7a 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -46,8 +46,6 @@ #if defined(OS_WIN) // TODO(port): accessibility not yet implemented. See http://crbug.com/8288. #include "chrome/browser/browser_accessibility_manager.h" -// TODO(port): The compact language detection library works only for Windows. -#include "third_party/cld/bar/toolbar/cld/i18n/encodings/compact_lang_det/win/cld_unicodetext.h" #endif using base::TimeDelta; @@ -423,10 +421,6 @@ void RenderViewHost::StopFinding(bool clear_selection) { Send(new ViewMsg_StopFinding(routing_id(), clear_selection)); } -void RenderViewHost::GetPageLanguage() { - Send(new ViewMsg_DeterminePageText(routing_id())); -} - void RenderViewHost::Zoom(PageZoom::Function function) { Send(new ViewMsg_Zoom(routing_id(), function)); } @@ -759,8 +753,6 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_DidFailProvisionalLoadWithError, OnMsgDidFailProvisionalLoadWithError) IPC_MESSAGE_HANDLER(ViewHostMsg_Find_Reply, OnMsgFindReply) - IPC_MESSAGE_HANDLER(ViewMsg_DeterminePageText_Reply, - OnDeterminePageTextReply) IPC_MESSAGE_HANDLER(ViewMsg_ExecuteCodeFinished, OnExecuteCodeFinished) IPC_MESSAGE_HANDLER(ViewHostMsg_UpdateFavIconURL, OnMsgUpdateFavIconURL) @@ -844,6 +836,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_AccessibilityFocusChange, OnAccessibilityFocusChange) IPC_MESSAGE_HANDLER(ViewHostMsg_OnCSSInserted, OnCSSInserted) + IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg)) IPC_END_MESSAGE_MAP_EX() @@ -1147,22 +1140,6 @@ void RenderViewHost::OnMsgFindReply(int request_id, Send(new ViewMsg_FindReplyACK(routing_id())); } -void RenderViewHost::OnDeterminePageTextReply( - const std::wstring& page_text) { -#if defined(OS_WIN) // Only for windows. - int num_languages = 0; - bool is_reliable = false; - const char* language_iso_code = LanguageCodeISO639_1( - DetectLanguageOfUnicodeText(page_text.c_str(), true, &is_reliable, - &num_languages, NULL)); - std::string language(language_iso_code); - NotificationService::current()->Notify( - NotificationType::TAB_LANGUAGE_DETERMINED, - Source<RenderViewHost>(this), - Details<std::string>(&language)); -#endif -} - void RenderViewHost::OnExecuteCodeFinished(int request_id, bool success) { std::pair<int, bool> result_details(request_id, success); NotificationService::current()->Notify( @@ -1783,3 +1760,13 @@ void RenderViewHost::OnAccessibilityFocusChange(int acc_obj_id) { void RenderViewHost::OnCSSInserted() { delegate_->DidInsertCSS(); } + +void RenderViewHost::OnPageContents(const GURL& url, + int32 page_id, + const std::wstring& contents) { + RenderViewHostDelegate::BrowserIntegration* integration_delegate = + delegate_->GetBrowserIntegrationDelegate(); + if (!integration_delegate) + return; + integration_delegate->OnPageContents(url, page_id, contents); +} diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 0d923ca..f3b1a32 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -212,12 +212,6 @@ class RenderViewHost : public RenderWidgetHost, // clear the selection on the focused frame. void StopFinding(bool clear_selection); - // Get the most probable language of the text content in the tab. This sends - // a message to the render view to get the content of the page as text. The - // caller gets the language via the NotificationService by registering to the - // NotificationType TAB_LANGUAGE_DETERMINED. - void GetPageLanguage(); - // Change the zoom level of a page. void Zoom(PageZoom::Function function); @@ -423,22 +417,22 @@ class RenderViewHost : public RenderWidgetHost, // Creates a new RenderWidget with the given route id. void CreateNewWidget(int route_id, bool activatable); - // Send the response to an extension api call. + // Sends the response to an extension api call. void SendExtensionResponse(int request_id, bool success, const std::string& response, const std::string& error); - // Send a response to an extension api call that it was blocked for lack of + // Sends a response to an extension api call that it was blocked for lack of // permission. void BlockExtensionRequest(int request_id); - // Notify the renderer that its view type has changed. + // Notifies the renderer that its view type has changed. void ViewTypeChanged(ViewType::Type type); - // Tell renderer which browser window it is being attached to. + // Tells the renderer which browser window it is being attached to. void UpdateBrowserWindowId(int window_id); - // Tell render view that custom context action has been selected. + // Tells the render view that a custom context action has been selected. void PerformCustomContextMenuAction(unsigned action); protected: @@ -495,7 +489,6 @@ class RenderViewHost : public RenderWidgetHost, const gfx::Rect& selection_rect, int active_match_ordinal, bool final_update); - void OnDeterminePageTextReply(const std::wstring& tab_text); void OnExecuteCodeFinished(int request_id, bool success); void OnMsgUpdateFavIconURL(int32 page_id, const GURL& icon_url); void OnMsgDidDownloadFavIcon(int id, @@ -593,6 +586,9 @@ class RenderViewHost : public RenderWidgetHost, void OnExtensionPostMessage(int port_id, const std::string& message); void OnAccessibilityFocusChange(int acc_obj_id); void OnCSSInserted(); + void OnPageContents(const GURL& url, + int32 page_id, + const std::wstring& contents); private: friend class TestRenderViewHost; diff --git a/chrome/browser/renderer_host/render_view_host_delegate.h b/chrome/browser/renderer_host/render_view_host_delegate.h index c3df62d..cf426f6 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -217,6 +217,11 @@ class RenderViewHostDelegate { virtual void OnDidGetApplicationInfo( int32 page_id, const webkit_glue::WebApplicationInfo& app_info) = 0; + + // Notification that the contents of the page has been loaded. + virtual void OnPageContents(const GURL& url, + int32 page_id, + const std::wstring& contents) = 0; }; // Resource ------------------------------------------------------------------ diff --git a/chrome/browser/tab_contents/navigation_entry.h b/chrome/browser/tab_contents/navigation_entry.h index 555edfc..a6ee1dc 100644 --- a/chrome/browser/tab_contents/navigation_entry.h +++ b/chrome/browser/tab_contents/navigation_entry.h @@ -382,6 +382,15 @@ class NavigationEntry { return restore_type_; } + // The ISO 639-1 language code (ex: en, fr, zh...) for the page. + // Can be empty if the language was not detected yet or is unknown. + void set_language(const std::string& language) { + language_ = language; + } + std::string language() const { + return language_; + } + private: // WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING // Session/Tab restore save portions of this class so that it can be recreated @@ -405,6 +414,7 @@ class NavigationEntry { GURL user_typed_url_; bool has_post_data_; RestoreType restore_type_; + std::string language_; // ISO 639-1 language code. // This is a cached version of the result of GetTitleForDisplay. It prevents // us from having to do URL formatting on the URL evey time the title is diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index fd97827..aba37d7 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -1070,10 +1070,6 @@ void TabContents::StopFinding(bool clear_selection) { render_view_host()->StopFinding(clear_selection); } -void TabContents::GetPageLanguage() { - render_view_host()->GetPageLanguage(); -} - void TabContents::OnSavePage() { // If we can not save the page, try to download it. if (!SavePackage::IsSavableContents(contents_mime_type())) { @@ -1729,6 +1725,36 @@ void TabContents::OnDidGetApplicationInfo( delegate()->OnDidGetApplicationInfo(this, page_id); } +void TabContents::OnPageContents(const GURL& url, + int32 page_id, + const std::wstring& 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). + if (!url.SchemeIsSecure()) { + Profile* p = profile(); + if (!p || p->IsOffTheRecord()) + return; + + HistoryService* hs = p->GetHistoryService(Profile::IMPLICIT_ACCESS); + if (hs) + hs->SetPageContents(url, contents); + } + + // Detect the page language. The detection happens on the file thread. + // We get the TAB_LANGUAGE_DETERMINED notification when the language has been + // detected. + registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, + Source<RenderViewHost>(render_view_host())); + cld_helper_ = new CLDHelper(render_view_host()->process()->id(), + render_view_host()->routing_id(), + page_id, contents); + cld_helper_->DetectLanguage(); +} + void TabContents::DidStartProvisionalLoadForFrame( RenderViewHost* render_view_host, bool is_main_frame, @@ -2590,6 +2616,20 @@ void TabContents::Observe(NotificationType type, } #endif + case NotificationType::TAB_LANGUAGE_DETERMINED: { + DCHECK(cld_helper_.get()); + DCHECK(cld_helper_->language() == *Details<std::string>(details).ptr()); + + registrar_.Remove(this, NotificationType::TAB_LANGUAGE_DETERMINED, + Source<RenderViewHost>(source)); + + NavigationEntry* entry = controller_.GetActiveEntry(); + if (entry && entry->page_id() == cld_helper_->page_id()) + entry->set_language(cld_helper_->language()); + cld_helper_.release(); + break; + } + default: NOTREACHED(); } diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 2a84b8c..bd74602 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -18,6 +18,7 @@ #include "base/scoped_ptr.h" #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/cancelable_request.h" +#include "chrome/browser/cld_helper.h" #include "chrome/browser/dom_ui/dom_ui_factory.h" #include "chrome/browser/download/save_package.h" #include "chrome/browser/fav_icon_helper.h" @@ -536,9 +537,6 @@ class TabContents : public PageNavigator, return last_search_result_; } - // Get the most probable language of the text content in the tab. - void GetPageLanguage(); - // Misc state & callbacks ---------------------------------------------------- // Set whether the contents should block javascript message boxes or not. @@ -812,6 +810,9 @@ class TabContents : public PageNavigator, virtual void OnDidGetApplicationInfo( int32 page_id, const webkit_glue::WebApplicationInfo& info); + virtual void OnPageContents(const GURL& url, + int32 page_id, + const std::wstring& contents); // RenderViewHostDelegate::Resource implementation. virtual void DidStartProvisionalLoadForFrame(RenderViewHost* render_view_host, @@ -1176,6 +1177,9 @@ class TabContents : public PageNavigator, // profile scoped_refptr<URLRequestContextGetter> request_context_; + // Used to retrieve the language of the current page. + scoped_refptr<CLDHelper> cld_helper_; + // --------------------------------------------------------------------------- DISALLOW_COPY_AND_ASSIGN(TabContents); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 2791031..70110e6 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -291,6 +291,8 @@ 'browser/chromeos/usb_mount_observer.h', 'browser/chromeos/version_loader.cc', 'browser/chromeos/version_loader.h', + 'browser/cld_helper.cc', + 'browser/cld_helper.h', 'browser/cocoa/about_ipc_bridge.h', 'browser/cocoa/about_ipc_bridge.mm', 'browser/cocoa/about_ipc_controller.h', diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index f157b52..44b9519 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -223,8 +223,9 @@ class NotificationType { // is the InfoBubble. INFO_BUBBLE_CREATED, - // Sent after a call to RenderViewHost::DeterminePageLanguage. The details - // are Details<std::string> and the source is Source<RenderViewHost>. + // Sent when the language (English, French...) for a page has been detected. + // The details Details<std::string> contain the ISO 639-1 language code and + // the source is Source<RenderViewHost>. TAB_LANGUAGE_DETERMINED, // Send after the code is run in specified tab. diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index d043b29..0051389 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -257,14 +257,6 @@ IPC_BEGIN_MESSAGES(View) string16 /* search_text */, WebKit::WebFindOptions) - // Send from the browser to the rendered to get the text content of the page. - IPC_MESSAGE_ROUTED0(ViewMsg_DeterminePageText) - - // Send from the renderer to the browser to return the text content of the - // page. - IPC_MESSAGE_ROUTED1(ViewMsg_DeterminePageText_Reply, - std::wstring /* the language */) - // Send from the renderer to the browser to return the script running result. IPC_MESSAGE_ROUTED2(ViewMsg_ExecuteCodeFinished, int, /* request id */ @@ -1127,7 +1119,7 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC_MESSAGE_ROUTED1(ViewHostMsg_UpdateSpellingPanelWithMisspelledWord, string16 /* the word to update the panel with */) - // Initiate a download based on user actions like 'ALT+click'. + // Initiates a download based on user actions like 'ALT+click'. IPC_MESSAGE_ROUTED2(ViewHostMsg_DownloadUrl, GURL /* url */, GURL /* referrer */) @@ -1145,9 +1137,11 @@ IPC_BEGIN_MESSAGES(ViewHost) bool /* out - success */, std::wstring /* out - prompt field */) - // Sets the contents for the given page (URL and page ID are the first two - // arguments) given the contents that is the 3rd. - IPC_MESSAGE_CONTROL3(ViewHostMsg_PageContents, GURL, int32, std::wstring) + // Provides the contents for the given page that was loaded recently. + IPC_MESSAGE_ROUTED3(ViewHostMsg_PageContents, + GURL /* URL of the page */, + int32 /* page id */, + std::wstring /*page contents */) // Specifies the URL as the first parameter (a wstring) and thumbnail as // binary data as the second parameter. @@ -1167,13 +1161,13 @@ IPC_BEGIN_MESSAGES(ViewHost) // user right clicked. IPC_MESSAGE_ROUTED1(ViewHostMsg_ContextMenu, ContextMenuParams) - // Request that the given URL be opened in the specified manner. + // Requests that the given URL be opened in the specified manner. IPC_MESSAGE_ROUTED3(ViewHostMsg_OpenURL, GURL /* url */, GURL /* referrer */, WindowOpenDisposition /* disposition */) - // Notify that the preferred size of the content changed. + // Notifies that the preferred size of the content changed. IPC_MESSAGE_ROUTED1(ViewHostMsg_DidContentsPreferredSizeChange, gfx::Size /* pref_size */) diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index baac373..c27fb1c 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -245,7 +245,6 @@ RenderView::RenderView(RenderThreadBase* render_thread, send_preferred_size_changes_(false), ALLOW_THIS_IN_INITIALIZER_LIST( notification_provider_(new NotificationProvider(this))), - determine_page_text_after_loading_stops_(false), view_type_(ViewType::INVALID), browser_window_id_(-1), last_top_level_navigation_page_id_(-1), @@ -430,7 +429,6 @@ void RenderView::OnMessageReceived(const IPC::Message& message) { IPC_MESSAGE_HANDLER(ViewMsg_CopyImageAt, OnCopyImageAt) IPC_MESSAGE_HANDLER(ViewMsg_ExecuteEditCommand, OnExecuteEditCommand) IPC_MESSAGE_HANDLER(ViewMsg_Find, OnFind) - IPC_MESSAGE_HANDLER(ViewMsg_DeterminePageText, OnDeterminePageText) IPC_MESSAGE_HANDLER(ViewMsg_Zoom, OnZoom) IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForLoadingHost, OnSetZoomLevelForLoadingHost) @@ -582,23 +580,18 @@ void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) { if (!preliminary_capture) last_indexed_page_id_ = load_id; - // get the URL for this page + // Get the URL for this page. GURL url(main_frame->url()); if (url.is_empty()) return; - // full text + // Retrieve the frame's full text. std::wstring contents; CaptureText(main_frame, &contents); if (contents.size()) { - // Send the text to the browser for indexing. - Send(new ViewHostMsg_PageContents(url, load_id, contents)); - } - - // Send over text content of this page to the browser. - if (determine_page_text_after_loading_stops_) { - determine_page_text_after_loading_stops_ = false; - Send(new ViewMsg_DeterminePageText_Reply(routing_id_, 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)); } // thumbnail @@ -610,15 +603,6 @@ void RenderView::CaptureText(WebFrame* frame, std::wstring* contents) { if (!frame) return; - // 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). - if (GURL(frame->url()).SchemeIsSecure()) - return; - #ifdef TIME_TEXT_RETRIEVAL double begin = time_util::GetHighResolutionTimeNow(); #endif @@ -2964,23 +2948,6 @@ void RenderView::OnFind(int request_id, const string16& search_text, } } -void RenderView::OnDeterminePageText() { - if (!is_loading_) { - if (!webview()) - return; - WebFrame* main_frame = webview()->mainFrame(); - std::wstring contents; - CaptureText(main_frame, &contents); - Send(new ViewMsg_DeterminePageText_Reply(routing_id_, contents)); - determine_page_text_after_loading_stops_ = false; - return; - } - - // We set |determine_page_text_after_loading_stops_| true here so that, - // after page has been loaded completely, the text in the page is captured. - determine_page_text_after_loading_stops_ = true; -} - void RenderView::DnsPrefetch(const std::vector<std::string>& host_names) { Send(new ViewHostMsg_DnsPrefetch(host_names)); } diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index c69a601..4ae9e38 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -939,9 +939,6 @@ class RenderView : public RenderWidget, // Hopds a reference to the service which provides desktop notifications. scoped_ptr<NotificationProvider> notification_provider_; - // Set to true if request for capturing page text has been made. - bool determine_page_text_after_loading_stops_; - // Holds state pertaining to a navigation that we initiated. This is held by // the WebDataSource::ExtraData attribute. We use pending_navigation_state_ // as a temporary holder for the state until the WebDataSource corresponding diff --git a/chrome/test/data/english_page.html b/chrome/test/data/english_page.html new file mode 100644 index 0000000..539920d --- /dev/null +++ b/chrome/test/data/english_page.html @@ -0,0 +1,6 @@ +<html> +<head><title>This page is in English</title></head> +<body> +No joke! This is a page written in English. Awesome don't you think? +</body> +</html> diff --git a/chrome/test/data/french_page.html b/chrome/test/data/french_page.html new file mode 100644 index 0000000..7fcf684 --- /dev/null +++ b/chrome/test/data/french_page.html @@ -0,0 +1,6 @@ +<html> +<head><title>Cette page est en Français</title></head> +<body> +Cette page a été rédigée en français. Saviez-vous que le Français est la langue officielle des jeux olympiques? Ça vous en bouche un coin, pas vrai? +</body> +</html> diff --git a/chrome/test/ui_test_utils.cc b/chrome/test/ui_test_utils.cc index 6723084..e4b5818 100644 --- a/chrome/test/ui_test_utils.cc +++ b/chrome/test/ui_test_utils.cc @@ -254,6 +254,33 @@ class SimpleNotificationObserver : public NotificationObserver { DISALLOW_COPY_AND_ASSIGN(SimpleNotificationObserver); }; +class LanguageDetectionNotificationObserver : public NotificationObserver { + public: + explicit LanguageDetectionNotificationObserver( + RenderViewHost* render_view_host) { + registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, + Source<RenderViewHost>(render_view_host)); + ui_test_utils::RunMessageLoop(); + } + + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + language_ = *(Details<std::string>(details).ptr()); + MessageLoopForUI::current()->Quit(); + } + + std::string language() const { + return language_; + } + + private: + NotificationRegistrar registrar_; + std::string language_; + + DISALLOW_COPY_AND_ASSIGN(LanguageDetectionNotificationObserver); +}; + class FindInPageNotificationObserver : public NotificationObserver { public: explicit FindInPageNotificationObserver(TabContents* parent_tab) @@ -484,6 +511,11 @@ void WaitForFocusInBrowser(Browser* browser) { browser); } +std::string WaitForLanguageDetection(TabContents* tab) { + LanguageDetectionNotificationObserver observer(tab->render_view_host()); + return observer.language(); +} + int FindInPage(TabContents* tab_contents, const string16& search_string, bool forward, bool match_case, int* ordinal) { tab_contents->StartFinding(search_string, forward, match_case); diff --git a/chrome/test/ui_test_utils.h b/chrome/test/ui_test_utils.h index 89dc8fc..2c4cd95 100644 --- a/chrome/test/ui_test_utils.h +++ b/chrome/test/ui_test_utils.h @@ -115,6 +115,10 @@ void WaitForFocusChange(RenderViewHost* rvh); // traversal). void WaitForFocusInBrowser(Browser* browser); +// Waits for the language of the page to have been detected and returns it. +// This should be called right after a navigation notification was received. +std::string WaitForLanguageDetection(TabContents* tab_contents); + // Performs a find in the page of the specified tab. Returns the number of // matches found. |ordinal| is an optional parameter which is set to the index // of the current match. |