diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 00:44:31 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-04-13 00:44:31 +0000 |
commit | 93b9d6948d212b630a115dc4b77bbe6bf2b3b671 (patch) | |
tree | 92e02d514f2b44cdd2b7f82063ed3e91af3773bf /chrome/browser/tab_contents | |
parent | 71504b42e176b37b9324897a53908df5ba6c723e (diff) | |
download | chromium_src-93b9d6948d212b630a115dc4b77bbe6bf2b3b671.zip chromium_src-93b9d6948d212b630a115dc4b77bbe6bf2b3b671.tar.gz chromium_src-93b9d6948d212b630a115dc4b77bbe6bf2b3b671.tar.bz2 |
Move code that talks to spelling and translate out of content. I create ChromeRenderObserver, which is a RenderViewObserver for the Chrome layer. Also, I added a TranslateTabHelper to hold the per-tab language data and moved LanguageState back to chrome since it's not used by content.
Review URL: http://codereview.chromium.org/6824068
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@81341 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/tab_contents')
-rw-r--r-- | chrome/browser/tab_contents/language_state.cc | 76 | ||||
-rw-r--r-- | chrome/browser/tab_contents/language_state.h | 109 | ||||
-rw-r--r-- | chrome/browser/tab_contents/render_view_context_menu.cc | 20 |
3 files changed, 198 insertions, 7 deletions
diff --git a/chrome/browser/tab_contents/language_state.cc b/chrome/browser/tab_contents/language_state.cc new file mode 100644 index 0000000..baf1bdd --- /dev/null +++ b/chrome/browser/tab_contents/language_state.cc @@ -0,0 +1,76 @@ +// 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/tab_contents/language_state.h" + +#include "content/browser/tab_contents/navigation_controller.h" +#include "content/browser/tab_contents/navigation_entry.h" + +LanguageState::LanguageState(NavigationController* nav_controller) + : navigation_controller_(nav_controller), + page_translatable_(false), + translation_pending_(false), + translation_declined_(false), + in_page_navigation_(false) { +} + +LanguageState::~LanguageState() { +} + +void LanguageState::DidNavigate( + const NavigationController::LoadCommittedDetails& details) { + in_page_navigation_ = details.is_in_page; + if (in_page_navigation_ || !details.is_main_frame) + return; // Don't reset our states, the page has not changed. + + bool reload = details.entry->transition_type() == PageTransition::RELOAD || + details.type == NavigationType::SAME_PAGE; + if (reload) { + // We might not get a LanguageDetermined notifications on reloads. Make sure + // to keep the original language and to set current_lang_ so + // IsPageTranslated() returns false. + current_lang_ = original_lang_; + } else { + prev_original_lang_ = original_lang_; + prev_current_lang_ = current_lang_; + original_lang_.clear(); + current_lang_.clear(); + } + + translation_pending_ = false; + translation_declined_ = false; +} + +void LanguageState::LanguageDetermined(const std::string& page_language, + bool page_translatable) { + if (in_page_navigation_ && !original_lang_.empty()) { + // In-page navigation, we don't expect our states to change. + // Note that we'll set the languages if original_lang_ is empty. This might + // happen if the we did not get called on the top-page. + return; + } + page_translatable_ = page_translatable; + original_lang_ = page_language; + current_lang_ = page_language; +} + +std::string LanguageState::AutoTranslateTo() const { + // Only auto-translate if: + // - no translation is pending + // - this page is in the same language as the previous page + // - the previous page had been translated + // - this page is not already translated + // - the new page was navigated through a link. + if (!translation_pending_ && + prev_original_lang_ == original_lang_ && + prev_original_lang_ != prev_current_lang_ && + original_lang_ == current_lang_ && + navigation_controller_->GetActiveEntry() && + navigation_controller_->GetActiveEntry()->transition_type() == + PageTransition::LINK) { + return prev_current_lang_; + } + + return std::string(); +} diff --git a/chrome/browser/tab_contents/language_state.h b/chrome/browser/tab_contents/language_state.h new file mode 100644 index 0000000..b9f4d33 --- /dev/null +++ b/chrome/browser/tab_contents/language_state.h @@ -0,0 +1,109 @@ +// 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_TAB_CONTENTS_LANGUAGE_STATE_H_ +#define CHROME_BROWSER_TAB_CONTENTS_LANGUAGE_STATE_H_ +#pragma once + +#include <string> + +#include "base/basictypes.h" +#include "content/browser/tab_contents/navigation_controller.h" + +// This class holds the language state of the current page. +// There is one LanguageState instance per TabContents. +// It is used to determine when navigating to a new page whether it should +// automatically be translated. +// This auto-translate behavior is the expected behavior when: +// - user is on page in language A that they had translated to language B. +// - user clicks a link in that page that takes them to a page also in language +// A. + +class LanguageState { + public: + explicit LanguageState(NavigationController* nav_controller); + ~LanguageState(); + + // Should be called when the page did a new navigation (whether it is a main + // frame or sub-frame navigation). + void DidNavigate(const NavigationController::LoadCommittedDetails& details); + + // Should be called when the language of the page has been determined. + // |page_translatable| when false indicates that the browser should not offer + // to translate the page. + void LanguageDetermined(const std::string& page_language, + bool page_translatable); + + // Returns the language the current page should be translated to, based on the + // previous page languages and the transition. This should be called after + // the language page has been determined. + // Returns an empty string if the page should not be auto-translated. + std::string AutoTranslateTo() const; + + // Returns true if the current page in the associated tab has been translated. + bool IsPageTranslated() const { return original_lang_ != current_lang_; } + + const std::string& original_language() const { return original_lang_; } + + void set_current_language(const std::string& language) { + current_lang_ = language; + } + const std::string& current_language() const { return current_lang_; } + + bool page_translatable() const { return page_translatable_; } + + // Whether the page is currently in the process of being translated. + bool translation_pending() const { return translation_pending_; } + void set_translation_pending(bool value) { translation_pending_ = value; } + + // Whether the user has already declined to translate the page. + bool translation_declined() const { return translation_declined_; } + void set_translation_declined(bool value) { translation_declined_ = value; } + + // Whether the current page was navigated through an in-page (fragment) + // navigation. + bool in_page_navigation() const { return in_page_navigation_; } + + private: + // The languages this page is in. Note that current_lang_ is different from + // original_lang_ when the page has been translated. + // Note that these might be empty if the page language has not been determined + // yet. + std::string original_lang_; + std::string current_lang_; + + // Same as above but for the previous page. + std::string prev_original_lang_; + std::string prev_current_lang_; + + // The navigation controller of the tab we are associated with. + NavigationController* navigation_controller_; + + // Whether it is OK to offer to translate the page. Some pages explictly + // specify that they should not be translated by the browser (this is the case + // for GMail for example, which provides its own translation features). + bool page_translatable_; + + // Whether a translation is currently pending (TabContents waiting for the + // PAGE_TRANSLATED notification). This is needed to avoid sending duplicate + // translate requests to a page. TranslateManager initiates translations + // when it received the LANGUAGE_DETERMINED notification. This is sent by + // the renderer with the page contents, every time the load stops for the + // main frame, so we may get several. + // TODO(jcampan): make the renderer send the language just once per navigation + // then we can get rid of that state. + bool translation_pending_; + + // Whether the user has declined to translate the page (by closing the infobar + // for example). This is necessary as a new infobar could be shown if a new + // load happens in the page after the user closed the infobar. + bool translation_declined_; + + // Whether the current navigation is a fragment navigation (in page). + bool in_page_navigation_; + + DISALLOW_COPY_AND_ASSIGN(LanguageState); +}; + +#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 |