| Index: chrome/renderer/translate/translate_helper.cc
|
| diff --git a/chrome/renderer/translate/translate_helper.cc b/chrome/renderer/translate/translate_helper.cc
|
| index 84e68fe966dce49dfb4caeaab5a99e6ac0ab2b7c..cf9804dd316ff086808365589f2baeb5b05f19a1 100644
|
| --- a/chrome/renderer/translate/translate_helper.cc
|
| +++ b/chrome/renderer/translate/translate_helper.cc
|
| @@ -93,18 +93,28 @@ void TranslateHelper::PageCaptured(const string16& contents) {
|
| // language of the intended audience (a distinction really only
|
| // relevant for things like langauge textbooks). This distinction
|
| // shouldn't affect translation.
|
| - WebDocument document = GetMainFrame()->document();
|
| + WebFrame* main_frame = GetMainFrame();
|
| + if (!main_frame)
|
| + return;
|
| + WebDocument document = main_frame->document();
|
| std::string content_language = document.contentLanguage().utf8();
|
| + WebElement html_element = document.documentElement();
|
| + std::string html_lang;
|
| + // |html_element| can be null element, e.g. in
|
| + // BrowserTest.WindowOpenClose.
|
| + if (!html_element.isNull())
|
| + html_lang = html_element.getAttribute("lang").utf8();
|
| std::string cld_language;
|
| bool is_cld_reliable;
|
| std::string language = DeterminePageLanguage(
|
| - content_language, contents, &cld_language, &is_cld_reliable);
|
| + content_language, html_lang, contents, &cld_language, &is_cld_reliable);
|
|
|
| if (language.empty())
|
| return;
|
|
|
| language_determined_time_ = base::TimeTicks::Now();
|
|
|
| + // TODO(toyoshim): Add |html_lang| to LanguageDetectionDetails.
|
| GURL url(document.url());
|
| LanguageDetectionDetails details;
|
| details.time = base::Time::Now();
|
| @@ -319,7 +329,20 @@ void TranslateHelper::ResetInvalidLanguageCode(std::string* code) {
|
| }
|
|
|
| // static
|
| +void TranslateHelper::ApplyLanguageCodeCorrection(std::string* code) {
|
| + // Correct well-known format errors.
|
| + CorrectLanguageCodeTypo(code);
|
| +
|
| + // Convert language code synonym firstly because sometime synonym code is in
|
| + // invalid format, e.g. 'fil'. After validation, such a 3 characters language
|
| + // gets converted to an empty string.
|
| + ConvertLanguageCodeSynonym(code);
|
| + ResetInvalidLanguageCode(code);
|
| +}
|
| +
|
| +// static
|
| std::string TranslateHelper::DeterminePageLanguage(const std::string& code,
|
| + const std::string& html_lang,
|
| const string16& contents,
|
| std::string* cld_language_p,
|
| bool* is_cld_reliable_p) {
|
| @@ -337,17 +360,27 @@ std::string TranslateHelper::DeterminePageLanguage(const std::string& code,
|
| ConvertLanguageCodeSynonym(&cld_language);
|
| #endif // defined(ENABLE_LANGUAGE_DETECTION)
|
|
|
| - // Correct well-known format errors.
|
| - std::string language = code;
|
| - CorrectLanguageCodeTypo(&language);
|
| + // Check if html lang attribute is valid.
|
| + std::string modified_html_lang;
|
| + if (!html_lang.empty()) {
|
| + modified_html_lang = html_lang;
|
| + ApplyLanguageCodeCorrection(&modified_html_lang);
|
| + TranslateHelperMetrics::ReportHtmlLang(html_lang, modified_html_lang);
|
| + VLOG(9) << "html lang based language code: " << modified_html_lang;
|
| + }
|
|
|
| - // Convert language code synonym firstly because sometime synonym code is in
|
| - // invalid format, e.g. 'fil'. After validation, such a 3 characters language
|
| - // gets converted to an empty string.
|
| - ConvertLanguageCodeSynonym(&language);
|
| - ResetInvalidLanguageCode(&language);
|
| + // Check if Content-Language is valid.
|
| + std::string modified_code;
|
| + if (!code.empty()) {
|
| + modified_code = code;
|
| + ApplyLanguageCodeCorrection(&modified_code);
|
| + TranslateHelperMetrics::ReportContentLanguage(code, modified_code);
|
| + }
|
|
|
| - TranslateHelperMetrics::ReportContentLanguage(code, language);
|
| + // Adopt |modified_html_lang| if it is valid. Otherwise, adopt
|
| + // |modified_code|.
|
| + std::string language = modified_html_lang.empty() ? modified_code :
|
| + modified_html_lang;
|
|
|
| #if defined(ENABLE_LANGUAGE_DETECTION)
|
| // If |language| is empty, just use CLD result even though it might be
|
| @@ -433,7 +466,8 @@ void TranslateHelper::OnTranslatePage(int page_id,
|
| const std::string& translate_script,
|
| const std::string& source_lang,
|
| const std::string& target_lang) {
|
| - if (render_view()->GetPageId() != page_id)
|
| + WebFrame* main_frame = GetMainFrame();
|
| + if (!main_frame || render_view()->GetPageId() != page_id)
|
| return; // We navigated away, nothing to do.
|
|
|
| if (translation_pending_ && page_id == page_id_ &&
|
| @@ -457,7 +491,7 @@ void TranslateHelper::OnTranslatePage(int page_id,
|
| TranslateHelperMetrics::ReportUserActionDuration(language_determined_time_,
|
| base::TimeTicks::Now());
|
|
|
| - GURL url(GetMainFrame()->document().url());
|
| + GURL url(main_frame->document().url());
|
| TranslateHelperMetrics::ReportPageScheme(url.scheme());
|
|
|
| if (!IsTranslateLibAvailable()) {
|
| @@ -590,12 +624,10 @@ void TranslateHelper::NotifyBrowserTranslationFailed(
|
|
|
| WebFrame* TranslateHelper::GetMainFrame() {
|
| WebView* web_view = render_view()->GetWebView();
|
| - if (!web_view) {
|
| - // When the WebView is going away, the render view should have called
|
| - // CancelPendingTranslation() which should have stopped any pending work, so
|
| - // that case should not happen.
|
| - NOTREACHED();
|
| +
|
| + // When the tab is going to be closed, the web_view can be NULL.
|
| + if (!web_view)
|
| return NULL;
|
| - }
|
| +
|
| return web_view->mainFrame();
|
| }
|
|
|