diff options
author | droger <droger@chromium.org> | 2014-09-10 04:11:25 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-09-10 11:13:06 +0000 |
commit | 5cd641278bef09e5c77424b7eb69f8ff1ca628bf (patch) | |
tree | 842e423f32aac0781bc82eefbd51625388401135 /components/translate | |
parent | 96d38dadb4ef427e56542c7316b755d47de680e4 (diff) | |
download | chromium_src-5cd641278bef09e5c77424b7eb69f8ff1ca628bf.zip chromium_src-5cd641278bef09e5c77424b7eb69f8ff1ca628bf.tar.gz chromium_src-5cd641278bef09e5c77424b7eb69f8ff1ca628bf.tar.bz2 |
Move navigation handling code from TranslateClient to TranslateDriver
This CL moves code from chrome/ (ChromeTranslateClient) to the
translate component (ContentTranslateDriver).
BUG=331509
Review URL: https://codereview.chromium.org/558663003
Cr-Commit-Position: refs/heads/master@{#294157}
Diffstat (limited to 'components/translate')
-rw-r--r-- | components/translate/content/browser/content_translate_driver.cc | 108 | ||||
-rw-r--r-- | components/translate/content/browser/content_translate_driver.h | 34 |
2 files changed, 139 insertions, 3 deletions
diff --git a/components/translate/content/browser/content_translate_driver.cc b/components/translate/content/browser/content_translate_driver.cc index 429e8cb..d135762 100644 --- a/components/translate/content/browser/content_translate_driver.cc +++ b/components/translate/content/browser/content_translate_driver.cc @@ -4,28 +4,70 @@ #include "components/translate/content/browser/content_translate_driver.h" +#include "base/bind.h" #include "base/logging.h" #include "components/translate/content/common/translate_messages.h" +#include "components/translate/core/browser/translate_download_manager.h" +#include "components/translate/core/browser/translate_manager.h" #include "content/public/browser/browser_context.h" #include "content/public/browser/navigation_controller.h" +#include "content/public/browser/navigation_details.h" #include "content/public/browser/navigation_entry.h" #include "content/public/browser/page_navigator.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" #include "content/public/common/referrer.h" +#include "net/http/http_status_code.h" #include "url/gurl.h" +namespace { + +// The maximum number of attempts we'll do to see if the page has finshed +// loading before giving up the translation +const int kMaxTranslateLoadCheckAttempts = 20; + +} // namespace + namespace translate { ContentTranslateDriver::ContentTranslateDriver( content::NavigationController* nav_controller) - : navigation_controller_(nav_controller), - observer_(NULL) { + : content::WebContentsObserver(nav_controller->GetWebContents()), + navigation_controller_(nav_controller), + translate_manager_(NULL), + observer_(NULL), + max_reload_check_attempts_(kMaxTranslateLoadCheckAttempts), + weak_pointer_factory_(this) { DCHECK(navigation_controller_); } ContentTranslateDriver::~ContentTranslateDriver() {} +void ContentTranslateDriver::InitiateTranslation(const std::string& page_lang, + int attempt) { + if (translate_manager_->GetLanguageState().translation_pending()) + return; + + // During a reload we need web content to be available before the + // translate script is executed. Otherwise we will run the translate script on + // an empty DOM which will fail. Therefore we wait a bit to see if the page + // has finished. + if (web_contents()->IsLoading() && attempt < max_reload_check_attempts_) { + int backoff = attempt * kMaxTranslateLoadCheckAttempts; + base::MessageLoop::current()->PostDelayedTask( + FROM_HERE, + base::Bind(&ContentTranslateDriver::InitiateTranslation, + weak_pointer_factory_.GetWeakPtr(), + page_lang, + attempt + 1), + base::TimeDelta::FromMilliseconds(backoff)); + return; + } + + translate_manager_->InitiateTranslation( + translate::TranslateDownloadManager::GetLanguageCode(page_lang)); +} + // TranslateDriver methods bool ContentTranslateDriver::IsLinkNavigation() { @@ -108,4 +150,66 @@ void ContentTranslateDriver::OpenUrlInNewTab(const GURL& url) { navigation_controller_->GetWebContents()->OpenURL(params); } +// content::WebContentsObserver methods + +void ContentTranslateDriver::NavigationEntryCommitted( + const content::LoadCommittedDetails& load_details) { + // Check whether this is a reload: When doing a page reload, the + // TranslateLanguageDetermined IPC is not sent so the translation needs to be + // explicitly initiated. + + content::NavigationEntry* entry = + web_contents()->GetController().GetActiveEntry(); + if (!entry) { + NOTREACHED(); + return; + } + + // If the navigation happened while offline don't show the translate + // bar since there will be nothing to translate. + if (load_details.http_status_code == 0 || + load_details.http_status_code == net::HTTP_INTERNAL_SERVER_ERROR) { + return; + } + + if (!load_details.is_main_frame && + translate_manager_->GetLanguageState().translation_declined()) { + // Some sites (such as Google map) may trigger sub-frame navigations + // when the user interacts with the page. We don't want to show a new + // infobar if the user already dismissed one in that case. + return; + } + + // If not a reload, return. + if (entry->GetTransitionType() != content::PAGE_TRANSITION_RELOAD && + load_details.type != content::NAVIGATION_TYPE_SAME_PAGE) { + return; + } + + if (!translate_manager_->GetLanguageState().page_needs_translation()) + return; + + // Note that we delay it as the ordering of the processing of this callback + // by WebContentsObservers is undefined and might result in the current + // infobars being removed. Since the translation initiation process might add + // an infobar, it must be done after that. + base::MessageLoop::current()->PostTask( + FROM_HERE, + base::Bind(&ContentTranslateDriver::InitiateTranslation, + weak_pointer_factory_.GetWeakPtr(), + translate_manager_->GetLanguageState().original_language(), + 0)); +} + +void ContentTranslateDriver::DidNavigateAnyFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) { + // Let the LanguageState clear its state. + const bool reload = + details.entry->GetTransitionType() == content::PAGE_TRANSITION_RELOAD || + details.type == content::NAVIGATION_TYPE_SAME_PAGE; + translate_manager_->GetLanguageState().DidNavigate( + details.is_in_page, details.is_main_frame, reload); +} + } // namespace translate diff --git a/components/translate/content/browser/content_translate_driver.h b/components/translate/content/browser/content_translate_driver.h index bae58bb..d9ef2c2 100644 --- a/components/translate/content/browser/content_translate_driver.h +++ b/components/translate/content/browser/content_translate_driver.h @@ -6,7 +6,9 @@ #define COMPONENTS_TRANSLATE_CONTENT_BROWSER_CONTENT_TRANSLATE_DRIVER_H_ #include "base/basictypes.h" +#include "base/memory/weak_ptr.h" #include "components/translate/core/browser/translate_driver.h" +#include "content/public/browser/web_contents_observer.h" namespace content { class NavigationController; @@ -15,8 +17,11 @@ class WebContents; namespace translate { +class TranslateManager; + // Content implementation of TranslateDriver. -class ContentTranslateDriver : public TranslateDriver { +class ContentTranslateDriver : public TranslateDriver, + public content::WebContentsObserver { public: // The observer for the ContentTranslateDriver. @@ -38,6 +43,19 @@ class ContentTranslateDriver : public TranslateDriver { // Sets the Observer. Calling this method is optional. void set_observer(Observer* observer) { observer_ = observer; } + // Number of attempts before waiting for a page to be fully reloaded. + void set_translate_max_reload_attempts(int attempts) { + max_reload_check_attempts_ = attempts; + } + + // Sets the TranslateManager associated with this driver. + void set_translate_manager(TranslateManager* manager) { + translate_manager_ = manager; + } + + // Initiates translation once the page is finished loading. + void InitiateTranslation(const std::string& page_lang, int attempt); + // TranslateDriver methods. virtual void OnIsPageTranslatedChanged() OVERRIDE; virtual void OnTranslateEnabledChanged() OVERRIDE; @@ -55,12 +73,26 @@ class ContentTranslateDriver : public TranslateDriver { virtual bool HasCurrentPage() OVERRIDE; virtual void OpenUrlInNewTab(const GURL& url) OVERRIDE; + // content::WebContentsObserver implementation. + virtual void NavigationEntryCommitted( + const content::LoadCommittedDetails& load_details) OVERRIDE; + virtual void DidNavigateAnyFrame( + const content::LoadCommittedDetails& details, + const content::FrameNavigateParams& params) OVERRIDE; + private: // The navigation controller of the tab we are associated with. content::NavigationController* navigation_controller_; + TranslateManager* translate_manager_; + Observer* observer_; + // Max number of attempts before checking if a page has been reloaded. + int max_reload_check_attempts_; + + base::WeakPtrFactory<ContentTranslateDriver> weak_pointer_factory_; + DISALLOW_COPY_AND_ASSIGN(ContentTranslateDriver); }; |