summaryrefslogtreecommitdiffstats
path: root/chrome/browser/tab_contents
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-13 00:44:31 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-13 00:44:31 +0000
commit93b9d6948d212b630a115dc4b77bbe6bf2b3b671 (patch)
tree92e02d514f2b44cdd2b7f82063ed3e91af3773bf /chrome/browser/tab_contents
parent71504b42e176b37b9324897a53908df5ba6c723e (diff)
downloadchromium_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.cc76
-rw-r--r--chrome/browser/tab_contents/language_state.h109
-rw-r--r--chrome/browser/tab_contents/render_view_context_menu.cc20
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