diff options
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/render_view.cc | 11 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 8 | ||||
-rw-r--r-- | chrome/renderer/translate/page_translator.cc | 70 | ||||
-rw-r--r-- | chrome/renderer/translate/page_translator.h | 36 | ||||
-rw-r--r-- | chrome/renderer/translate/page_translator_unittest.cc | 4 |
5 files changed, 98 insertions, 31 deletions
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..17a57a8 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::Delegate { 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::Delegate 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..f18de8a 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, + Delegate* 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..68d18d4 100644 --- a/chrome/renderer/translate/page_translator.h +++ b/chrome/renderer/translate/page_translator.h @@ -31,15 +31,24 @@ class WebString; // and delegates the actual text translation to a TextTranslator. class PageTranslator : public TextTranslator::Delegate { public: + class Delegate { + public: + virtual ~Delegate() {} + 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, Delegate* 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 +89,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). + Delegate* delegate_; // The TextTranslator is responsible for translating the actual text chunks // from one language to another. @@ -98,6 +107,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. |