| Index: components/translate/content/browser/content_translate_driver.cc
|
| diff --git a/components/translate/content/browser/content_translate_driver.cc b/components/translate/content/browser/content_translate_driver.cc
|
| index 429e8cbfe14bfee6aa54f6ce8f1eb51ca6376734..d1357620d1a5df6fe7bfc86091139ec0819156e0 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
|
|
|