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(); |
} |