diff options
author | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-01 08:45:15 +0000 |
---|---|---|
committer | jcampan@chromium.org <jcampan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-02-01 08:45:15 +0000 |
commit | 7e0831b90c618af96931fcbd0908c4fd05ae0ec5 (patch) | |
tree | 6ae2ee1358ecb452ed7c06335ddd643ee47bc109 | |
parent | 6db4b6c354f638cfe9beb849ca0ad0beb1bb4a8d (diff) | |
download | chromium_src-7e0831b90c618af96931fcbd0908c4fd05ae0ec5.zip chromium_src-7e0831b90c618af96931fcbd0908c4fd05ae0ec5.tar.gz chromium_src-7e0831b90c618af96931fcbd0908c4fd05ae0ec5.tar.bz2 |
Relanding the hooking of the translate feature UI.
See http://codereview.chromium.org/549217
Review URL: http://codereview.chromium.org/558065
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37688 0039d316-1c4b-4281-b951-d872f2087c98
21 files changed, 340 insertions, 60 deletions
diff --git a/chrome/browser/browser_main.cc b/chrome/browser/browser_main.cc index 42d2c14..a0ba774 100644 --- a/chrome/browser/browser_main.cc +++ b/chrome/browser/browser_main.cc @@ -46,6 +46,7 @@ #include "chrome/browser/profile_manager.h" #include "chrome/browser/renderer_host/resource_dispatcher_host.h" #include "chrome/browser/shell_integration.h" +#include "chrome/browser/translate/translate_manager.h" #include "chrome/browser/user_data_manager.h" #include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" @@ -803,6 +804,13 @@ int BrowserMain(const MainFunctionParams& parameters) { process_singleton.Create(); +#if defined(OS_WIN) + // Create the TranslateManager singleton. + // TODO(jcampan): enable on non Windows platforms when the info-bars are + // implemented. + Singleton<TranslateManager>::get(); +#endif + // Show the First Run UI if this is the first time Chrome has been run on // this computer, or we're being compelled to do so by a command line flag. // Note that this be done _after_ the PrefService is initialized and all diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index 7b9aef0..f85f054 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -897,7 +897,7 @@ bool DetectTabLanguageFunction::RunImpl() { // The tab contents does not know its language yet. Let's wait until it // receives it, or until the tab is closed/navigates to some other page. registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, - Source<RenderViewHost>(contents->render_view_host())); + Source<TabContents>(contents)); registrar_.Add(this, NotificationType::TAB_CLOSING, Source<NavigationController>(&(contents->controller()))); registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index cb0eddf..820b575 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -825,6 +825,7 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { OnAccessibilityFocusChange) IPC_MESSAGE_HANDLER(ViewHostMsg_OnCSSInserted, OnCSSInserted) IPC_MESSAGE_HANDLER(ViewHostMsg_PageContents, OnPageContents) + IPC_MESSAGE_HANDLER(ViewHostMsg_PageTranslated, OnPageTranslated) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(RenderWidgetHost::OnMessageReceived(msg)) IPC_END_MESSAGE_MAP_EX() @@ -1794,3 +1795,14 @@ void RenderViewHost::OnPageContents(const GURL& url, integration_delegate->OnPageContents(url, process()->id(), page_id, contents, language); } + +void RenderViewHost::OnPageTranslated(int32 page_id, + const std::string& original_lang, + const std::string& translated_lang) { + RenderViewHostDelegate::BrowserIntegration* integration_delegate = + delegate_->GetBrowserIntegrationDelegate(); + if (!integration_delegate) + return; + integration_delegate->OnPageTranslated(page_id, + original_lang, translated_lang); +} diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 5890ae7..764be45 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -606,6 +606,9 @@ class RenderViewHost : public RenderWidgetHost { int32 page_id, const std::wstring& contents, const std::string& language); + void OnPageTranslated(int32 page_id, + const std::string& original_lang, + const std::string& translated_lang); 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 680ff0f..892aa86 100644 --- a/chrome/browser/renderer_host/render_view_host_delegate.h +++ b/chrome/browser/renderer_host/render_view_host_delegate.h @@ -223,6 +223,11 @@ class RenderViewHostDelegate { int32 page_id, const std::wstring& contents, const std::string& language) = 0; + + // Notification that the page has been translated. + virtual void OnPageTranslated(int32 page_id, + const std::string& original_lang, + const std::string& translated_lang) = 0; }; // Resource ------------------------------------------------------------------ diff --git a/chrome/browser/tab_contents/tab_contents.cc b/chrome/browser/tab_contents/tab_contents.cc index a575ae5..4641f3b 100644 --- a/chrome/browser/tab_contents/tab_contents.cc +++ b/chrome/browser/tab_contents/tab_contents.cc @@ -772,6 +772,16 @@ void TabContents::ShowPageInfo(const GURL& url, delegate_->ShowPageInfo(profile(), url, ssl, show_history); } +void TabContents::TranslatePage(const std::string& source_lang, + const std::string& target_lang) { + NavigationEntry* entry = controller_.GetActiveEntry(); + if (!entry) { + NOTREACHED(); + return; + } + render_view_host()->TranslatePage(entry->page_id(), source_lang, target_lang); +} + ConstrainedWindow* TabContents::CreateConstrainedDialog( ConstrainedWindowDelegate* delegate) { ConstrainedWindow* window = @@ -1813,26 +1823,24 @@ void TabContents::OnPageContents(const GURL& url, entry->set_language(language); } - if (CommandLine::ForCurrentProcess()->HasSwitch( - switches::kAutoPageTranslate) && - TranslationService::IsTranslationEnabled()) { - std::string locale = g_browser_process->GetApplicationLocale(); - if (!locale.empty() && locale != language) { - // Don't translate the NTP, download page, history... - if (entry && !entry->url().SchemeIs("chrome") && - TranslationService::ShouldTranslatePage(language, locale)) { - render_view_host()->TranslatePage(entry->page_id(), language, locale); - } - } - } - std::string lang = language; NotificationService::current()->Notify( NotificationType::TAB_LANGUAGE_DETERMINED, - Source<RenderViewHost>(render_view_host()), + Source<TabContents>(this), Details<std::string>(&lang)); } +void TabContents::OnPageTranslated(int32 page_id, + const std::string& original_lang, + const std::string& translated_lang) { + std::pair<std::string, std::string> lang_pair = + std::make_pair(original_lang, translated_lang); + NotificationService::current()->Notify( + NotificationType::PAGE_TRANSLATED, + Source<TabContents>(this), + Details<std::pair<std::string, std::string> >(&lang_pair)); +} + void TabContents::DidStartProvisionalLoadForFrame( RenderViewHost* render_view_host, bool is_main_frame, diff --git a/chrome/browser/tab_contents/tab_contents.h b/chrome/browser/tab_contents/tab_contents.h index 9586f88..e42c1fb 100644 --- a/chrome/browser/tab_contents/tab_contents.h +++ b/chrome/browser/tab_contents/tab_contents.h @@ -350,6 +350,10 @@ class TabContents : public PageNavigator, const NavigationEntry::SSLStatus& ssl, bool show_history); + // Translates the page contents from |source_lang| to |target_lang|. + void TranslatePage(const std::string& source_lang, + const std::string& target_lang); + // Window management --------------------------------------------------------- // Create a new window constrained to this TabContents' clip and visibility. @@ -827,6 +831,9 @@ class TabContents : public PageNavigator, int32 page_id, const std::wstring& contents, const std::string& language); + virtual void OnPageTranslated(int32 page_id, + const std::string& original_lang, + const std::string& translated_lang); // RenderViewHostDelegate::Resource implementation. virtual void DidStartProvisionalLoadForFrame(RenderViewHost* render_view_host, diff --git a/chrome/browser/translate/translate_infobars_delegates.cc b/chrome/browser/translate/translate_infobars_delegates.cc index ecf0a95..15d165b 100644 --- a/chrome/browser/translate/translate_infobars_delegates.cc +++ b/chrome/browser/translate/translate_infobars_delegates.cc @@ -93,10 +93,7 @@ void TranslateInfoBarDelegate::GetAvailableTargetLanguages( } void TranslateInfoBarDelegate::Translate() { - // TODO(kuan): Call actual Translate method. -/* - Translate(WideToUTF8(original_language()), WideToUTF8(target_language())); -*/ + tab_contents_->TranslatePage(original_language_, target_language_); } bool TranslateInfoBarDelegate::IsLanguageBlacklisted() { diff --git a/chrome/browser/translate/translate_manager.cc b/chrome/browser/translate/translate_manager.cc new file mode 100644 index 0000000..5a7938a --- /dev/null +++ b/chrome/browser/translate/translate_manager.cc @@ -0,0 +1,113 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/translate/translate_manager.h" + +#include "chrome/browser/browser_process.h" +#include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/translation_service.h" +#include "chrome/browser/tab_contents/navigation_controller.h" +#include "chrome/browser/tab_contents/navigation_entry.h" +#include "chrome/browser/tab_contents/tab_contents.h" +#include "chrome/browser/translate/translate_infobars_delegates.h" +#include "chrome/browser/translate/translate_prefs.h" +#include "chrome/common/notification_details.h" +#include "chrome/common/notification_service.h" +#include "chrome/common/notification_source.h" +#include "chrome/common/notification_type.h" +#include "chrome/common/pref_service.h" + +TranslateManager::~TranslateManager() { +} + +void TranslateManager::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + switch (type.value) { + case NotificationType::NAV_ENTRY_COMMITTED: { + // We have navigated to a new page. + NavigationController* controller = + Source<NavigationController>(source).ptr(); + NavigationEntry* entry = controller->GetActiveEntry(); + if (!entry->language().empty()) { + // The language for that page is known (it must be a back/forward + // navigation to a page we already visited). + InitiateTranslation(controller->tab_contents(), entry->language()); + } + break; + } + case NotificationType::TAB_LANGUAGE_DETERMINED: { + TabContents* tab = Source<TabContents>(source).ptr(); + std::string language = *(Details<std::string>(details).ptr()); + InitiateTranslation(tab, language); + break; + } + case NotificationType::PAGE_TRANSLATED: { + TabContents* tab = Source<TabContents>(source).ptr(); + std::pair<std::string, std::string>* language_pair = + (Details<std::pair<std::string, std::string> >(details).ptr()); + PrefService* prefs = GetPrefService(tab); + tab->AddInfoBar(new AfterTranslateInfoBarDelegate(tab, prefs, + language_pair->first, + language_pair->second)); + break; + } + default: + NOTREACHED(); + } +} + +TranslateManager::TranslateManager() { + if (!TranslationService::IsTranslationEnabled()) + return; + + notification_registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED, + NotificationService::AllSources()); + notification_registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, + NotificationService::AllSources()); + notification_registrar_.Add(this, NotificationType::PAGE_TRANSLATED, + NotificationService::AllSources()); +} + +void TranslateManager::InitiateTranslation(TabContents* tab, + const std::string& page_lang) { + PrefService* prefs = GetPrefService(tab); + NavigationEntry* entry = tab->controller().GetActiveEntry(); + if (!entry) { + NOTREACHED(); + return; + } + + std::string chrome_lang = g_browser_process->GetApplicationLocale(); + + // We don't want to translate: + // - any Chrome specific page (New Tab Page, Download, History... pages). + // - similar languages (ex: en-US to en). + // - any user black-listed URLs or user selected language combination. + if (entry->url().SchemeIs("chrome") || page_lang == chrome_lang || + !TranslationService::ShouldTranslatePage(page_lang, chrome_lang) || + !TranslatePrefs::CanTranslate(prefs, page_lang, entry->url())) { + return; + } + if (TranslatePrefs::ShouldAutoTranslate(prefs, page_lang, chrome_lang)) { + // The user has previously select "always translate" for this language. + tab->TranslatePage(page_lang, chrome_lang); + return; + } + + // Prompts the user if he/she wants the page translated. + tab->AddInfoBar(new BeforeTranslateInfoBarDelegate(tab, prefs, + entry->url(), + page_lang, chrome_lang)); +} + +PrefService* TranslateManager::GetPrefService(TabContents* tab) { + PrefService* prefs = NULL; + if (tab->profile()) + prefs = tab->profile()->GetPrefs(); + if (prefs) + return prefs; + + return g_browser_process->local_state(); +} diff --git a/chrome/browser/translate/translate_manager.h b/chrome/browser/translate/translate_manager.h new file mode 100644 index 0000000..b51f089 --- /dev/null +++ b/chrome/browser/translate/translate_manager.h @@ -0,0 +1,47 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_ +#define CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_ + +#include <string> + +#include "base/singleton.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" + +class PrefService; +class TabContents; + +// The TranslateManager class is responsible for showing an info-bar when a page +// in a language different than the user language is loaded. It triggers the +// page translation the user requests. +// It is a singleton. + +class TranslateManager : public NotificationObserver { + public: + virtual ~TranslateManager(); + + // NotificationObserver implementation: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: + friend struct DefaultSingletonTraits<TranslateManager>; + + TranslateManager(); + + // Starts the translation process on |tab| containing the page in the + // |page_lang| language. + void InitiateTranslation(TabContents* tab, const std::string& page_lang); + + // Convenience method that retrieves the PrefService. + PrefService* GetPrefService(TabContents* tab); + + NotificationRegistrar notification_registrar_; + + DISALLOW_COPY_AND_ASSIGN(TranslateManager); +}; + +#endif // CHROME_BROWSER_TRANSLATE_TRANSLATE_MANAGER_H_ diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index c3d1ba5..06ca294 100755 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1677,6 +1677,8 @@ 'browser/translate/options_menu_model.h', 'browser/translate/translate_infobars_delegates.cc', 'browser/translate/translate_infobars_delegates.h', + 'browser/translate/translate_manager.cc', + 'browser/translate/translate_manager.h', 'browser/translate/translate_prefs.cc', 'browser/translate/translate_prefs.h', 'browser/user_data_manager.cc', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 574752a..85739da 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -31,10 +31,6 @@ const char kApp[] = "app"; // automation-related messages on IPC channel with the given ID. const char kAutomationClientChannelID[] = "automation-channel"; -// Makes Chrome translate any page loaded which is not in the locale Chrome -// is running in. -const char kAutoPageTranslate[] = "auto-translate"; - // Enables the bookmark menu. const char kBookmarkMenu[] = "bookmark-menu"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 4f8d4d6..69db6fa 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -24,7 +24,6 @@ extern const char kAllowSandboxDebugging[]; extern const char kAlwaysEnableDevTools[]; extern const char kApp[]; extern const char kAutomationClientChannelID[]; -extern const char kAutoPageTranslate[]; extern const char kBookmarkMenu[]; extern const char kBrowserAssertTest[]; extern const char kBrowserCrashTest[]; diff --git a/chrome/common/notification_type.h b/chrome/common/notification_type.h index f05482f..9e336e0 100644 --- a/chrome/common/notification_type.h +++ b/chrome/common/notification_type.h @@ -225,9 +225,15 @@ class NotificationType { // 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>. + // the source is Source<TabContents>. TAB_LANGUAGE_DETERMINED, + // Sent when a page has been translated. The source is the tab for that page + // (Source<TabContents>) and the details are the language the page was + // originally in and the language it was translated to + // (std::pair<std::string, std::string>). + PAGE_TRANSLATED, + // Sent after the renderer returns a snapshot of tab contents. TAB_SNAPSHOT_TAKEN, diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h index 55414a7..b7ad8d4 100644 --- a/chrome/common/render_messages_internal.h +++ b/chrome/common/render_messages_internal.h @@ -1989,6 +1989,12 @@ IPC_BEGIN_MESSAGES(ViewHost) IPC_MESSAGE_ROUTED1(ViewHostMsg_PageLanguageDetermined, std::string /* the language */) + // Notifies the browser that a page has been translated. + IPC_MESSAGE_ROUTED3(ViewHostMsg_PageTranslated, + int, /* page id */ + std::string /* the original language */, + std::string /* the translated language */) + //--------------------------------------------------------------------------- // Socket Stream messages: // These are messages from the SocketStreamHandle to the browser. diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index d4c1c36..5eea4b3 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -312,7 +312,7 @@ RenderView::RenderView(RenderThreadBase* render_thread, webkit_preferences_(webkit_preferences), session_storage_namespace_id_(session_storage_namespace_id), ALLOW_THIS_IN_INITIALIZER_LIST(text_translator_(this)) { - page_translator_.reset(new PageTranslator(&text_translator_)); + page_translator_.reset(new PageTranslator(&text_translator_, this)); } RenderView::~RenderView() { @@ -2872,6 +2872,13 @@ void RenderView::DidStopLoadingForPlugin() { didStopLoading(); } +void RenderView::PageTranslated(int page_id, + const std::string& original_lang, + const std::string& target_lang) { + Send(new ViewHostMsg_PageTranslated(routing_id_, page_id_, + original_lang, target_lang)); +} + void RenderView::ShowModalHTMLDialogForPlugin( const GURL& url, const gfx::Size& size, @@ -3376,7 +3383,7 @@ void RenderView::OnTranslatePage(int page_id, WebFrame* main_frame = webview()->mainFrame(); if (!main_frame) return; - page_translator_->Translate(main_frame, source_lang, target_lang); + page_translator_->Translate(page_id, main_frame, source_lang, target_lang); } void RenderView::OnTranslateTextResponse( diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index a96ee39..3523238 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -123,7 +123,8 @@ class RenderView : public RenderWidget, public WebKit::WebFrameClient, public WebKit::WebPageSerializerClient, public webkit_glue::WebPluginPageDelegate, - public base::SupportsWeakPtr<RenderView> { + public base::SupportsWeakPtr<RenderView>, + public PageTranslator::PageTranslatorDelegate { public: // Visit all RenderViews with a live WebView (i.e., RenderViews that have // been closed but not yet destroyed are excluded). @@ -387,6 +388,11 @@ class RenderView : public RenderWidget, const std::string& json_arguments, std::string* json_retval); + // PageTranslator::PageTranslatorDelegate implementation: + virtual void PageTranslated(int page_id, + const std::string& original_lang, + const std::string& target_lang); + // Do not delete directly. This class is reference counted. virtual ~RenderView(); diff --git a/chrome/renderer/translate/page_translator.cc b/chrome/renderer/translate/page_translator.cc index df0a59b..ab4d806 100644 --- a/chrome/renderer/translate/page_translator.cc +++ b/chrome/renderer/translate/page_translator.cc @@ -44,8 +44,11 @@ bool PageTranslator::WebStringCompare::operator()( return len1 < len2; } -PageTranslator::PageTranslator(TextTranslator* text_translator) - : text_translator_(text_translator) { +PageTranslator::PageTranslator(TextTranslator* text_translator, + PageTranslatorDelegate* delegate) + : delegate_(delegate), + text_translator_(text_translator), + page_id_(-1) { for (size_t i = 0; i < arraysize(kSkippedTags); ++i) ignored_tags_.insert(WebKit::WebString(ASCIIToUTF16(kSkippedTags[i]))); for (size_t i = 0; i < arraysize(kInlineTags); ++i) @@ -53,13 +56,35 @@ PageTranslator::PageTranslator(TextTranslator* text_translator) } PageTranslator::~PageTranslator() { - STLDeleteContainerPairSecondPointers(pending_translations_.begin(), - pending_translations_.end()); + ResetPageStates(); // This deletes pending translations. } -void PageTranslator::Translate(WebKit::WebFrame* web_frame, - std::string from_lang, - std::string to_lang) { +void PageTranslator::Translate(int page_id, + WebKit::WebFrame* web_frame, + std::string source_lang, + std::string target_lang) { + if (page_id != page_id_) { + // This is a new page, our states are invalid. + ResetPageStates(); + page_id_ = page_id; + } + if (original_language_.empty()) { + original_language_ = source_lang; + current_language_ = source_lang; + } + if (original_language_ != current_language_) { + // The page has already been translated. + if (target_lang == current_language_) { + NOTREACHED(); + return; + } + // TODO(jcampan): implement translation of an already translated page. + return; + } + + // We are about to start the translation process. + current_language_ = target_lang; + std::stack<NodeList*> node_list_stack; std::vector<NodeList*> text_node_lists; TraverseNode(web_frame->document(), &node_list_stack, &text_node_lists); @@ -85,15 +110,15 @@ void PageTranslator::Translate(WebKit::WebFrame* web_frame, // Send the text for translation. bool secure = static_cast<GURL>(web_frame->top()->url()).SchemeIsSecure(); int work_id = - text_translator_->Translate(text_chunks, from_lang, to_lang, secure, - this); + text_translator_->Translate(text_chunks, source_lang, target_lang, + secure, this); pending_translations_[work_id] = *iter; } } void PageTranslator::NavigatedToNewPage() { // We can drop all our states, they were related to the previous page. - ResetPageState(); + ResetPageStates(); } void PageTranslator::UndoTranslation() { @@ -102,8 +127,11 @@ void PageTranslator::UndoTranslation() { for (iter = text_nodes_.begin(); iter != text_nodes_.end(); ++iter) iter->first.setNodeValue(iter->second); - // The page is back to its original content, we can dop all our states. - ResetPageState(); + // The page is back to its original content, we can dop all our states but the + // page id. + int page_id = page_id_; + ResetPageStates(); + page_id_ = page_id; } bool PageTranslator::ShouldElementBeTraversed(WebKit::WebElement element) { @@ -125,11 +153,6 @@ void PageTranslator::ClearNodeZone(int work_id) { pending_translations_.erase(iter); } -void PageTranslator::ResetPageState() { - pending_translations_.clear(); - text_nodes_.clear(); -} - void PageTranslator::TranslationError(int work_id, int error_id) { // TODO(jcampan): may be we should show somehow that something went wrong to // the user? @@ -152,6 +175,7 @@ void PageTranslator::TextTranslated( // anchor tags. // NOTREACHED() << "Translation results received are inconsistent with the " // "request"; + ClearNodeZone(work_id); return; } @@ -159,6 +183,9 @@ void PageTranslator::TextTranslated( (*nodes)[i].setNodeValue(WebKit::WebString(translated_text_chunks[i])); ClearNodeZone(work_id); + + if (delegate_ && pending_translations_.empty()) + delegate_->PageTranslated(page_id_, original_language_, current_language_); } void PageTranslator::TraverseNode(WebKit::WebNode node, @@ -208,3 +235,12 @@ void PageTranslator::TraverseNode(WebKit::WebNode node, delete text_nodes; } } + +void PageTranslator::ResetPageStates() { + page_id_ = -1; + original_language_.clear(); + current_language_.clear(); + text_nodes_.clear(); + // Remove pending translations. + STLDeleteValues(&pending_translations_); +} diff --git a/chrome/renderer/translate/page_translator.h b/chrome/renderer/translate/page_translator.h index 14139227..08de0b1 100644 --- a/chrome/renderer/translate/page_translator.h +++ b/chrome/renderer/translate/page_translator.h @@ -31,15 +31,29 @@ class WebString; // and delegates the actual text translation to a TextTranslator. class PageTranslator : public TextTranslator::Delegate { public: + // Note that we don't use the simpler name Delegate as it seems to freak-out + // the VisualStudio 2005 compiler in render_view.cc. (RenderView would be + // implementing PageTranslator::Delegate that somehow confuses the compiler + // into thinking we are talkin about TextTranslator::Delegate.) + class PageTranslatorDelegate { + public: + virtual ~PageTranslatorDelegate() {} + virtual void PageTranslated(int page_id, + const std::string& original_lang, + const std::string& target_lang) = 0; + }; + // The caller remains the owner of |text_translator|. - explicit PageTranslator(TextTranslator* text_translator); + PageTranslator(TextTranslator* text_translator, + PageTranslatorDelegate* delegate); virtual ~PageTranslator(); - // Starts the translation process of |web_frame| from |from_lang| to |to_lang| - // where the languages are the ISO codes (ex: en, fr...). - void Translate(WebKit::WebFrame* web_frame, - std::string from_lang, - std::string to_lang); + // Starts the translation process of |web_frame| from |source_lang| to + // |target_lang| where the languages are the ISO codes (ex: en, fr...). + void Translate(int page_id, + WebKit::WebFrame* web_frame, + std::string source_lang, + std::string target_lang); // Notification that the associated RenderView has navigated to a new page. void NavigatedToNewPage(); @@ -80,10 +94,10 @@ class PageTranslator : public TextTranslator::Delegate { void ClearNodeZone(int work_id); // Clears all the states related to the page's contents. - void ResetPageState(); + void ResetPageStates(); - // The RenderView we are providing translations for. - RenderView* render_view_; + // Our delegate (notified when a page is translated). + PageTranslatorDelegate* delegate_; // The TextTranslator is responsible for translating the actual text chunks // from one language to another. @@ -98,6 +112,15 @@ class PageTranslator : public TextTranslator::Delegate { // Mapping from a translation engine work id to the associated nodes. std::map<int, NodeList*> pending_translations_; + // The language the page was in originally. + std::string original_language_; + + // The language the page was translated to. + std::string current_language_; + + // The page id of the page last time we translated. + int page_id_; + // The list of text nodes in the current page with their original text. // Used to undo the translation. typedef std::pair<WebKit::WebNode, WebKit::WebString> NodeTextPair; diff --git a/chrome/renderer/translate/page_translator_unittest.cc b/chrome/renderer/translate/page_translator_unittest.cc index 4bc1e02..4ab6c482 100644 --- a/chrome/renderer/translate/page_translator_unittest.cc +++ b/chrome/renderer/translate/page_translator_unittest.cc @@ -168,8 +168,8 @@ TEST_F(TranslatorTest, DISABLED_TranslatePages) { // Translate it. ReverseTextTranslator text_translator; - PageTranslator translator(&text_translator); - translator.Translate(web_frame, "en", "fr"); + PageTranslator translator(&text_translator, NULL); + translator.Translate(0, web_frame, "en", "fr"); // Translation is asynchronous, so we need to process the pending messages // to make it happen. diff --git a/chrome/test/ui_test_utils.cc b/chrome/test/ui_test_utils.cc index 4c04d20..3dc51ec 100644 --- a/chrome/test/ui_test_utils.cc +++ b/chrome/test/ui_test_utils.cc @@ -259,10 +259,9 @@ class SimpleNotificationObserver : public NotificationObserver { class LanguageDetectionNotificationObserver : public NotificationObserver { public: - explicit LanguageDetectionNotificationObserver( - RenderViewHost* render_view_host) { + explicit LanguageDetectionNotificationObserver(TabContents* tab) { registrar_.Add(this, NotificationType::TAB_LANGUAGE_DETERMINED, - Source<RenderViewHost>(render_view_host)); + Source<TabContents>(tab)); ui_test_utils::RunMessageLoop(); } @@ -522,7 +521,7 @@ void WaitForFocusInBrowser(Browser* browser) { } std::string WaitForLanguageDetection(TabContents* tab) { - LanguageDetectionNotificationObserver observer(tab->render_view_host()); + LanguageDetectionNotificationObserver observer(tab); return observer.language(); } |