| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/renderer/translate/translate_helper.h" | 5 #include "chrome/renderer/translate/translate_helper.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/compiler_specific.h" | 8 #include "base/compiler_specific.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/message_loop.h" | 10 #include "base/message_loop.h" |
| 11 #include "base/strings/string16.h" | 11 #include "base/strings/string16.h" |
| 12 #include "base/strings/string_split.h" | |
| 13 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 15 #include "chrome/common/chrome_constants.h" | 14 #include "chrome/common/chrome_constants.h" |
| 16 #include "chrome/common/render_messages.h" | 15 #include "chrome/common/render_messages.h" |
| 17 #include "chrome/common/translate/translate_util.h" | 16 #include "chrome/common/translate/language_detection_util.h" |
| 18 #include "chrome/renderer/translate/translate_helper_metrics.h" | 17 #include "chrome/common/translate/translate_common_metrics.h" |
| 19 #include "content/public/renderer/render_view.h" | 18 #include "content/public/renderer/render_view.h" |
| 20 #include "third_party/WebKit/public/web/WebDocument.h" | 19 #include "third_party/WebKit/public/web/WebDocument.h" |
| 21 #include "third_party/WebKit/public/web/WebElement.h" | 20 #include "third_party/WebKit/public/web/WebElement.h" |
| 22 #include "third_party/WebKit/public/web/WebFrame.h" | 21 #include "third_party/WebKit/public/web/WebFrame.h" |
| 23 #include "third_party/WebKit/public/web/WebNode.h" | 22 #include "third_party/WebKit/public/web/WebNode.h" |
| 24 #include "third_party/WebKit/public/web/WebNodeList.h" | 23 #include "third_party/WebKit/public/web/WebNodeList.h" |
| 25 #include "third_party/WebKit/public/web/WebScriptSource.h" | 24 #include "third_party/WebKit/public/web/WebScriptSource.h" |
| 26 #include "third_party/WebKit/public/web/WebView.h" | 25 #include "third_party/WebKit/public/web/WebView.h" |
| 27 #include "v8/include/v8.h" | 26 #include "v8/include/v8.h" |
| 28 | 27 |
| 29 #if defined(ENABLE_LANGUAGE_DETECTION) | |
| 30 #include "third_party/cld/encodings/compact_lang_det/win/cld_unicodetext.h" | |
| 31 #endif | |
| 32 | |
| 33 using WebKit::WebDocument; | 28 using WebKit::WebDocument; |
| 34 using WebKit::WebElement; | 29 using WebKit::WebElement; |
| 35 using WebKit::WebFrame; | 30 using WebKit::WebFrame; |
| 36 using WebKit::WebNode; | 31 using WebKit::WebNode; |
| 37 using WebKit::WebNodeList; | 32 using WebKit::WebNodeList; |
| 38 using WebKit::WebScriptSource; | 33 using WebKit::WebScriptSource; |
| 39 using WebKit::WebString; | 34 using WebKit::WebString; |
| 40 using WebKit::WebView; | 35 using WebKit::WebView; |
| 41 | 36 |
| 42 namespace { | 37 namespace { |
| 43 | 38 |
| 44 // The delay in milliseconds that we'll wait before checking to see if the | 39 // The delay in milliseconds that we'll wait before checking to see if the |
| 45 // translate library injected in the page is ready. | 40 // translate library injected in the page is ready. |
| 46 const int kTranslateInitCheckDelayMs = 150; | 41 const int kTranslateInitCheckDelayMs = 150; |
| 47 | 42 |
| 48 // The maximum number of times we'll check to see if the translate library | 43 // The maximum number of times we'll check to see if the translate library |
| 49 // injected in the page is ready. | 44 // injected in the page is ready. |
| 50 const int kMaxTranslateInitCheckAttempts = 5; | 45 const int kMaxTranslateInitCheckAttempts = 5; |
| 51 | 46 |
| 52 // The delay we wait in milliseconds before checking whether the translation has | 47 // The delay we wait in milliseconds before checking whether the translation has |
| 53 // finished. | 48 // finished. |
| 54 const int kTranslateStatusCheckDelayMs = 400; | 49 const int kTranslateStatusCheckDelayMs = 400; |
| 55 | 50 |
| 56 // Language name passed to the Translate element for it to detect the language. | 51 // Language name passed to the Translate element for it to detect the language. |
| 57 const char kAutoDetectionLanguage[] = "auto"; | 52 const char kAutoDetectionLanguage[] = "auto"; |
| 58 | 53 |
| 59 // Similar language code list. Some languages are very similar and difficult | |
| 60 // for CLD to distinguish. | |
| 61 struct SimilarLanguageCode { | |
| 62 const char* const code; | |
| 63 int group; | |
| 64 }; | |
| 65 | |
| 66 const SimilarLanguageCode kSimilarLanguageCodes[] = { | |
| 67 {"bs", 1}, | |
| 68 {"hr", 1}, | |
| 69 {"hi", 2}, | |
| 70 {"ne", 2}, | |
| 71 }; | |
| 72 | |
| 73 // Checks |kSimilarLanguageCodes| and returns group code. | |
| 74 int GetSimilarLanguageGroupCode(const std::string& language) { | |
| 75 for (size_t i = 0; i < arraysize(kSimilarLanguageCodes); ++i) { | |
| 76 if (language.find(kSimilarLanguageCodes[i].code) != 0) | |
| 77 continue; | |
| 78 return kSimilarLanguageCodes[i].group; | |
| 79 } | |
| 80 return 0; | |
| 81 } | |
| 82 | |
| 83 // Well-known languages which often have wrong server configuration of | |
| 84 // Content-Language: en. | |
| 85 // TODO(toyoshim): Remove these static tables and caller functions to | |
| 86 // chrome/common/translate, and implement them as std::set<>. | |
| 87 const char* kWellKnownCodesOnWrongConfiguration[] = { | |
| 88 "es", "pt", "ja", "ru", "de", "zh-CN", "zh-TW", "ar", "id", "fr", "it", "th" | |
| 89 }; | |
| 90 | |
| 91 } // namespace | 54 } // namespace |
| 92 | 55 |
| 93 //////////////////////////////////////////////////////////////////////////////// | 56 //////////////////////////////////////////////////////////////////////////////// |
| 94 // TranslateHelper, public: | 57 // TranslateHelper, public: |
| 95 // | 58 // |
| 96 TranslateHelper::TranslateHelper(content::RenderView* render_view) | 59 TranslateHelper::TranslateHelper(content::RenderView* render_view) |
| 97 : content::RenderViewObserver(render_view), | 60 : content::RenderViewObserver(render_view), |
| 98 page_id_(-1), | 61 page_id_(-1), |
| 99 translation_pending_(false), | 62 translation_pending_(false), |
| 100 weak_method_factory_(this) { | 63 weak_method_factory_(this) { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 121 WebDocument document = main_frame->document(); | 84 WebDocument document = main_frame->document(); |
| 122 std::string content_language = document.contentLanguage().utf8(); | 85 std::string content_language = document.contentLanguage().utf8(); |
| 123 WebElement html_element = document.documentElement(); | 86 WebElement html_element = document.documentElement(); |
| 124 std::string html_lang; | 87 std::string html_lang; |
| 125 // |html_element| can be null element, e.g. in | 88 // |html_element| can be null element, e.g. in |
| 126 // BrowserTest.WindowOpenClose. | 89 // BrowserTest.WindowOpenClose. |
| 127 if (!html_element.isNull()) | 90 if (!html_element.isNull()) |
| 128 html_lang = html_element.getAttribute("lang").utf8(); | 91 html_lang = html_element.getAttribute("lang").utf8(); |
| 129 std::string cld_language; | 92 std::string cld_language; |
| 130 bool is_cld_reliable; | 93 bool is_cld_reliable; |
| 131 std::string language = DeterminePageLanguage( | 94 std::string language = LanguageDetectionUtil::DeterminePageLanguage( |
| 132 content_language, html_lang, contents, &cld_language, &is_cld_reliable); | 95 content_language, html_lang, contents, &cld_language, &is_cld_reliable); |
| 133 | 96 |
| 134 if (language.empty()) | 97 if (language.empty()) |
| 135 return; | 98 return; |
| 136 | 99 |
| 137 language_determined_time_ = base::TimeTicks::Now(); | 100 language_determined_time_ = base::TimeTicks::Now(); |
| 138 | 101 |
| 139 GURL url(document.url()); | 102 GURL url(document.url()); |
| 140 LanguageDetectionDetails details; | 103 LanguageDetectionDetails details; |
| 141 details.time = base::Time::Now(); | 104 details.time = base::Time::Now(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 156 IsTranslationAllowed(&document) && !language.empty())); | 119 IsTranslationAllowed(&document) && !language.empty())); |
| 157 } | 120 } |
| 158 | 121 |
| 159 void TranslateHelper::CancelPendingTranslation() { | 122 void TranslateHelper::CancelPendingTranslation() { |
| 160 weak_method_factory_.InvalidateWeakPtrs(); | 123 weak_method_factory_.InvalidateWeakPtrs(); |
| 161 translation_pending_ = false; | 124 translation_pending_ = false; |
| 162 source_lang_.clear(); | 125 source_lang_.clear(); |
| 163 target_lang_.clear(); | 126 target_lang_.clear(); |
| 164 } | 127 } |
| 165 | 128 |
| 166 #if defined(ENABLE_LANGUAGE_DETECTION) | |
| 167 // static | |
| 168 std::string TranslateHelper::DetermineTextLanguage(const string16& text, | |
| 169 bool* is_cld_reliable) { | |
| 170 std::string language = chrome::kUnknownLanguageCode; | |
| 171 int num_languages = 0; | |
| 172 int text_bytes = 0; | |
| 173 bool is_reliable = false; | |
| 174 Language cld_language = | |
| 175 DetectLanguageOfUnicodeText(NULL, text.c_str(), true, &is_reliable, | |
| 176 &num_languages, NULL, &text_bytes); | |
| 177 if (is_cld_reliable != NULL) | |
| 178 *is_cld_reliable = is_reliable; | |
| 179 | |
| 180 // We don't trust the result if the CLD reports that the detection is not | |
| 181 // reliable, or if the actual text used to detect the language was less than | |
| 182 // 100 bytes (short texts can often lead to wrong results). | |
| 183 // TODO(toyoshim): CLD provides |is_reliable| flag. But, it just says that | |
| 184 // the determined language code is correct with 50% confidence. Chrome should | |
| 185 // handle the real confidence value to judge. | |
| 186 if (is_reliable && text_bytes >= 100 && cld_language != NUM_LANGUAGES && | |
| 187 cld_language != UNKNOWN_LANGUAGE && cld_language != TG_UNKNOWN_LANGUAGE) { | |
| 188 // We should not use LanguageCode_ISO_639_1 because it does not cover all | |
| 189 // the languages CLD can detect. As a result, it'll return the invalid | |
| 190 // language code for tradtional Chinese among others. | |
| 191 // |LanguageCodeWithDialect| will go through ISO 639-1, ISO-639-2 and | |
| 192 // 'other' tables to do the 'right' thing. In addition, it'll return zh-CN | |
| 193 // for Simplified Chinese. | |
| 194 language = LanguageCodeWithDialects(cld_language); | |
| 195 } | |
| 196 VLOG(9) << "Detected lang_id: " << language << ", from Text:\n" << text | |
| 197 << "\n*************************************\n"; | |
| 198 return language; | |
| 199 } | |
| 200 #endif // defined(ENABLE_LANGUAGE_DETECTION) | |
| 201 | |
| 202 //////////////////////////////////////////////////////////////////////////////// | 129 //////////////////////////////////////////////////////////////////////////////// |
| 203 // TranslateHelper, protected: | 130 // TranslateHelper, protected: |
| 204 // | 131 // |
| 205 bool TranslateHelper::IsTranslateLibAvailable() { | 132 bool TranslateHelper::IsTranslateLibAvailable() { |
| 206 return ExecuteScriptAndGetBoolResult( | 133 return ExecuteScriptAndGetBoolResult( |
| 207 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " | 134 "typeof cr != 'undefined' && typeof cr.googleTranslate != 'undefined' && " |
| 208 "typeof cr.googleTranslate.translate == 'function'", false); | 135 "typeof cr.googleTranslate.translate == 'function'", false); |
| 209 } | 136 } |
| 210 | 137 |
| 211 bool TranslateHelper::IsTranslateLibReady() { | 138 bool TranslateHelper::IsTranslateLibReady() { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 296 NOTREACHED(); | 223 NOTREACHED(); |
| 297 return 0.0; | 224 return 0.0; |
| 298 } | 225 } |
| 299 | 226 |
| 300 return v->NumberValue(); | 227 return v->NumberValue(); |
| 301 } | 228 } |
| 302 | 229 |
| 303 //////////////////////////////////////////////////////////////////////////////// | 230 //////////////////////////////////////////////////////////////////////////////// |
| 304 // TranslateHelper, private: | 231 // TranslateHelper, private: |
| 305 // | 232 // |
| 306 // static | |
| 307 void TranslateHelper::CorrectLanguageCodeTypo(std::string* code) { | |
| 308 DCHECK(code); | |
| 309 | |
| 310 size_t coma_index = code->find(','); | |
| 311 if (coma_index != std::string::npos) { | |
| 312 // There are more than 1 language specified, just keep the first one. | |
| 313 *code = code->substr(0, coma_index); | |
| 314 } | |
| 315 TrimWhitespaceASCII(*code, TRIM_ALL, code); | |
| 316 | |
| 317 // An underscore instead of a dash is a frequent mistake. | |
| 318 size_t underscore_index = code->find('_'); | |
| 319 if (underscore_index != std::string::npos) | |
| 320 (*code)[underscore_index] = '-'; | |
| 321 | |
| 322 // Change everything up to a dash to lower-case and everything after to upper. | |
| 323 size_t dash_index = code->find('-'); | |
| 324 if (dash_index != std::string::npos) { | |
| 325 *code = StringToLowerASCII(code->substr(0, dash_index)) + | |
| 326 StringToUpperASCII(code->substr(dash_index)); | |
| 327 } else { | |
| 328 *code = StringToLowerASCII(*code); | |
| 329 } | |
| 330 } | |
| 331 | |
| 332 // static | |
| 333 bool TranslateHelper::IsValidLanguageCode(const std::string& code) { | |
| 334 // Roughly check if the language code follows /[a-zA-Z]{2,3}(-[a-zA-Z]{2})?/. | |
| 335 // TODO(hajimehoshi): How about es-419, which is used as an Accept language? | |
| 336 std::vector<std::string> chunks; | |
| 337 base::SplitString(code, '-', &chunks); | |
| 338 | |
| 339 if (chunks.size() < 1 || 2 < chunks.size()) | |
| 340 return false; | |
| 341 | |
| 342 const std::string& main_code = chunks[0]; | |
| 343 | |
| 344 if (main_code.size() < 1 || 3 < main_code.size()) | |
| 345 return false; | |
| 346 | |
| 347 for (std::string::const_iterator it = main_code.begin(); | |
| 348 it != main_code.end(); ++it) { | |
| 349 if (!IsAsciiAlpha(*it)) | |
| 350 return false; | |
| 351 } | |
| 352 | |
| 353 if (chunks.size() == 1) | |
| 354 return true; | |
| 355 | |
| 356 const std::string& sub_code = chunks[1]; | |
| 357 | |
| 358 if (sub_code.size() != 2) | |
| 359 return false; | |
| 360 | |
| 361 for (std::string::const_iterator it = sub_code.begin(); | |
| 362 it != sub_code.end(); ++it) { | |
| 363 if (!IsAsciiAlpha(*it)) | |
| 364 return false; | |
| 365 } | |
| 366 | |
| 367 return true; | |
| 368 } | |
| 369 | |
| 370 // static | |
| 371 void TranslateHelper::ApplyLanguageCodeCorrection(std::string* code) { | |
| 372 // Correct well-known format errors. | |
| 373 CorrectLanguageCodeTypo(code); | |
| 374 | |
| 375 if (!IsValidLanguageCode(*code)) { | |
| 376 *code = std::string(); | |
| 377 return; | |
| 378 } | |
| 379 | |
| 380 TranslateUtil::ToTranslateLanguageSynonym(code); | |
| 381 } | |
| 382 | |
| 383 // static | |
| 384 bool TranslateHelper::IsSameOrSimilarLanguages( | |
| 385 const std::string& page_language, const std::string& cld_language) { | |
| 386 // Language code part of |page_language| is matched to one of |cld_language|. | |
| 387 // Country code is ignored here. | |
| 388 if (page_language.size() >= 2 && | |
| 389 cld_language.find(page_language.c_str(), 0, 2) == 0) { | |
| 390 // Languages are matched strictly. Reports false to metrics, but returns | |
| 391 // true. | |
| 392 TranslateHelperMetrics::ReportSimilarLanguageMatch(false); | |
| 393 return true; | |
| 394 } | |
| 395 | |
| 396 // Check if |page_language| and |cld_language| are in the similar language | |
| 397 // list and belong to the same language group. | |
| 398 int page_code = GetSimilarLanguageGroupCode(page_language); | |
| 399 bool match = page_code != 0 && | |
| 400 page_code == GetSimilarLanguageGroupCode(cld_language); | |
| 401 | |
| 402 TranslateHelperMetrics::ReportSimilarLanguageMatch(match); | |
| 403 return match; | |
| 404 } | |
| 405 | |
| 406 // static | |
| 407 bool TranslateHelper::MaybeServerWrongConfiguration( | |
| 408 const std::string& page_language, const std::string& cld_language) { | |
| 409 // If |page_language| is not "en-*", respect it and just return false here. | |
| 410 if (!StartsWithASCII(page_language, "en", false)) | |
| 411 return false; | |
| 412 | |
| 413 // A server provides a language meta information representing "en-*". But it | |
| 414 // might be just a default value due to missing user configuration. | |
| 415 // Let's trust |cld_language| if the determined language is not difficult to | |
| 416 // distinguish from English, and the language is one of well-known languages | |
| 417 // which often provide "en-*" meta information mistakenly. | |
| 418 for (size_t i = 0; i < arraysize(kWellKnownCodesOnWrongConfiguration); ++i) { | |
| 419 if (cld_language == kWellKnownCodesOnWrongConfiguration[i]) | |
| 420 return true; | |
| 421 } | |
| 422 return false; | |
| 423 } | |
| 424 | |
| 425 // static | |
| 426 bool TranslateHelper::CanCLDComplementSubCode( | |
| 427 const std::string& page_language, const std::string& cld_language) { | |
| 428 // Translate server cannot treat general Chinese. If Content-Language and | |
| 429 // CLD agree that the language is Chinese and Content-Language doesn't know | |
| 430 // which dialect is used, CLD language has priority. | |
| 431 // TODO(hajimehoshi): How about the other dialects like zh-MO? | |
| 432 return page_language == "zh" && StartsWithASCII(cld_language, "zh-", false); | |
| 433 } | |
| 434 | |
| 435 // static | |
| 436 std::string TranslateHelper::DeterminePageLanguage(const std::string& code, | |
| 437 const std::string& html_lang, | |
| 438 const string16& contents, | |
| 439 std::string* cld_language_p, | |
| 440 bool* is_cld_reliable_p) { | |
| 441 #if defined(ENABLE_LANGUAGE_DETECTION) | |
| 442 base::TimeTicks begin_time = base::TimeTicks::Now(); | |
| 443 bool is_cld_reliable; | |
| 444 std::string cld_language = DetermineTextLanguage(contents, &is_cld_reliable); | |
| 445 TranslateHelperMetrics::ReportLanguageDetectionTime(begin_time, | |
| 446 base::TimeTicks::Now()); | |
| 447 | |
| 448 if (cld_language_p != NULL) | |
| 449 *cld_language_p = cld_language; | |
| 450 if (is_cld_reliable_p != NULL) | |
| 451 *is_cld_reliable_p = is_cld_reliable; | |
| 452 TranslateUtil::ToTranslateLanguageSynonym(&cld_language); | |
| 453 #endif // defined(ENABLE_LANGUAGE_DETECTION) | |
| 454 | |
| 455 // Check if html lang attribute is valid. | |
| 456 std::string modified_html_lang; | |
| 457 if (!html_lang.empty()) { | |
| 458 modified_html_lang = html_lang; | |
| 459 ApplyLanguageCodeCorrection(&modified_html_lang); | |
| 460 TranslateHelperMetrics::ReportHtmlLang(html_lang, modified_html_lang); | |
| 461 VLOG(9) << "html lang based language code: " << modified_html_lang; | |
| 462 } | |
| 463 | |
| 464 // Check if Content-Language is valid. | |
| 465 std::string modified_code; | |
| 466 if (!code.empty()) { | |
| 467 modified_code = code; | |
| 468 ApplyLanguageCodeCorrection(&modified_code); | |
| 469 TranslateHelperMetrics::ReportContentLanguage(code, modified_code); | |
| 470 } | |
| 471 | |
| 472 // Adopt |modified_html_lang| if it is valid. Otherwise, adopt | |
| 473 // |modified_code|. | |
| 474 std::string language = modified_html_lang.empty() ? modified_code : | |
| 475 modified_html_lang; | |
| 476 | |
| 477 #if defined(ENABLE_LANGUAGE_DETECTION) | |
| 478 // If |language| is empty, just use CLD result even though it might be | |
| 479 // chrome::kUnknownLanguageCode. | |
| 480 if (language.empty()) { | |
| 481 TranslateHelperMetrics::ReportLanguageVerification( | |
| 482 TranslateHelperMetrics::LANGUAGE_VERIFICATION_CLD_ONLY); | |
| 483 return cld_language; | |
| 484 } | |
| 485 | |
| 486 if (cld_language == chrome::kUnknownLanguageCode) { | |
| 487 TranslateHelperMetrics::ReportLanguageVerification( | |
| 488 TranslateHelperMetrics::LANGUAGE_VERIFICATION_UNKNOWN); | |
| 489 return language; | |
| 490 } else if (IsSameOrSimilarLanguages(language, cld_language)) { | |
| 491 TranslateHelperMetrics::ReportLanguageVerification( | |
| 492 TranslateHelperMetrics::LANGUAGE_VERIFICATION_CLD_AGREE); | |
| 493 return language; | |
| 494 } else if (MaybeServerWrongConfiguration(language, cld_language)) { | |
| 495 TranslateHelperMetrics::ReportLanguageVerification( | |
| 496 TranslateHelperMetrics::LANGUAGE_VERIFICATION_TRUST_CLD); | |
| 497 return cld_language; | |
| 498 } else if (CanCLDComplementSubCode(language, cld_language)) { | |
| 499 TranslateHelperMetrics::ReportLanguageVerification( | |
| 500 TranslateHelperMetrics::LANGUAGE_VERIFICATION_CLD_COMPLEMENT_SUB_CODE); | |
| 501 return cld_language; | |
| 502 } else { | |
| 503 TranslateHelperMetrics::ReportLanguageVerification( | |
| 504 TranslateHelperMetrics::LANGUAGE_VERIFICATION_CLD_DISAGREE); | |
| 505 // Content-Language value might be wrong because CLD says that this page | |
| 506 // is written in another language with confidence. | |
| 507 // In this case, Chrome doesn't rely on any of the language codes, and | |
| 508 // gives up suggesting a translation. | |
| 509 return std::string(chrome::kUnknownLanguageCode); | |
| 510 } | |
| 511 #else // defined(ENABLE_LANGUAGE_DETECTION) | |
| 512 TranslateHelperMetrics::ReportLanguageVerification( | |
| 513 TranslateHelperMetrics::LANGUAGE_VERIFICATION_CLD_DISABLED); | |
| 514 #endif // defined(ENABLE_LANGUAGE_DETECTION) | |
| 515 | |
| 516 return language; | |
| 517 } | |
| 518 | 233 |
| 519 // static | 234 // static |
| 520 bool TranslateHelper::IsTranslationAllowed(WebDocument* document) { | 235 bool TranslateHelper::IsTranslationAllowed(WebDocument* document) { |
| 521 WebElement head = document->head(); | 236 WebElement head = document->head(); |
| 522 if (head.isNull() || !head.hasChildNodes()) | 237 if (head.isNull() || !head.hasChildNodes()) |
| 523 return true; | 238 return true; |
| 524 | 239 |
| 525 const WebString meta(ASCIIToUTF16("meta")); | 240 const WebString meta(ASCIIToUTF16("meta")); |
| 526 const WebString name(ASCIIToUTF16("name")); | 241 const WebString name(ASCIIToUTF16("name")); |
| 527 const WebString google(ASCIIToUTF16("google")); | 242 const WebString google(ASCIIToUTF16("google")); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 582 | 297 |
| 583 // Set our states. | 298 // Set our states. |
| 584 translation_pending_ = true; | 299 translation_pending_ = true; |
| 585 | 300 |
| 586 // If the source language is undetermined, we'll let the translate element | 301 // If the source language is undetermined, we'll let the translate element |
| 587 // detect it. | 302 // detect it. |
| 588 source_lang_ = (source_lang != chrome::kUnknownLanguageCode) ? | 303 source_lang_ = (source_lang != chrome::kUnknownLanguageCode) ? |
| 589 source_lang : kAutoDetectionLanguage; | 304 source_lang : kAutoDetectionLanguage; |
| 590 target_lang_ = target_lang; | 305 target_lang_ = target_lang; |
| 591 | 306 |
| 592 TranslateHelperMetrics::ReportUserActionDuration(language_determined_time_, | 307 TranslateCommonMetrics::ReportUserActionDuration(language_determined_time_, |
| 593 base::TimeTicks::Now()); | 308 base::TimeTicks::Now()); |
| 594 | 309 |
| 595 GURL url(main_frame->document().url()); | 310 GURL url(main_frame->document().url()); |
| 596 TranslateHelperMetrics::ReportPageScheme(url.scheme()); | 311 TranslateCommonMetrics::ReportPageScheme(url.scheme()); |
| 597 | 312 |
| 598 if (!IsTranslateLibAvailable()) { | 313 if (!IsTranslateLibAvailable()) { |
| 599 // Evaluate the script to add the translation related method to the global | 314 // Evaluate the script to add the translation related method to the global |
| 600 // context of the page. | 315 // context of the page. |
| 601 ExecuteScript(translate_script); | 316 ExecuteScript(translate_script); |
| 602 DCHECK(IsTranslateLibAvailable()); | 317 DCHECK(IsTranslateLibAvailable()); |
| 603 } | 318 } |
| 604 | 319 |
| 605 TranslatePageImpl(0); | 320 TranslatePageImpl(0); |
| 606 } | 321 } |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 } | 364 } |
| 650 | 365 |
| 651 if (!translation_pending_) { | 366 if (!translation_pending_) { |
| 652 NOTREACHED(); | 367 NOTREACHED(); |
| 653 return; | 368 return; |
| 654 } | 369 } |
| 655 | 370 |
| 656 translation_pending_ = false; | 371 translation_pending_ = false; |
| 657 | 372 |
| 658 // Check JavaScript performance counters for UMA reports. | 373 // Check JavaScript performance counters for UMA reports. |
| 659 TranslateHelperMetrics::ReportTimeToTranslate( | 374 TranslateCommonMetrics::ReportTimeToTranslate( |
| 660 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.translationTime")); | 375 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.translationTime")); |
| 661 | 376 |
| 662 // Notify the browser we are done. | 377 // Notify the browser we are done. |
| 663 render_view()->Send(new ChromeViewHostMsg_PageTranslated( | 378 render_view()->Send(new ChromeViewHostMsg_PageTranslated( |
| 664 render_view()->GetRoutingID(), render_view()->GetPageId(), | 379 render_view()->GetRoutingID(), render_view()->GetPageId(), |
| 665 actual_source_lang, target_lang_, TranslateErrors::NONE)); | 380 actual_source_lang, target_lang_, TranslateErrors::NONE)); |
| 666 return; | 381 return; |
| 667 } | 382 } |
| 668 | 383 |
| 669 // The translation is still pending, check again later. | 384 // The translation is still pending, check again later. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 690 FROM_HERE, | 405 FROM_HERE, |
| 691 base::Bind(&TranslateHelper::TranslatePageImpl, | 406 base::Bind(&TranslateHelper::TranslatePageImpl, |
| 692 weak_method_factory_.GetWeakPtr(), | 407 weak_method_factory_.GetWeakPtr(), |
| 693 count), | 408 count), |
| 694 AdjustDelay(count * kTranslateInitCheckDelayMs)); | 409 AdjustDelay(count * kTranslateInitCheckDelayMs)); |
| 695 return; | 410 return; |
| 696 } | 411 } |
| 697 | 412 |
| 698 // The library is loaded, and ready for translation now. | 413 // The library is loaded, and ready for translation now. |
| 699 // Check JavaScript performance counters for UMA reports. | 414 // Check JavaScript performance counters for UMA reports. |
| 700 TranslateHelperMetrics::ReportTimeToBeReady( | 415 TranslateCommonMetrics::ReportTimeToBeReady( |
| 701 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.readyTime")); | 416 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.readyTime")); |
| 702 TranslateHelperMetrics::ReportTimeToLoad( | 417 TranslateCommonMetrics::ReportTimeToLoad( |
| 703 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.loadTime")); | 418 ExecuteScriptAndGetDoubleResult("cr.googleTranslate.loadTime")); |
| 704 | 419 |
| 705 if (!StartTranslation()) { | 420 if (!StartTranslation()) { |
| 706 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); | 421 NotifyBrowserTranslationFailed(TranslateErrors::TRANSLATION_ERROR); |
| 707 return; | 422 return; |
| 708 } | 423 } |
| 709 // Check the status of the translation. | 424 // Check the status of the translation. |
| 710 base::MessageLoop::current()->PostDelayedTask( | 425 base::MessageLoop::current()->PostDelayedTask( |
| 711 FROM_HERE, | 426 FROM_HERE, |
| 712 base::Bind(&TranslateHelper::CheckTranslateStatus, | 427 base::Bind(&TranslateHelper::CheckTranslateStatus, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 725 | 440 |
| 726 WebFrame* TranslateHelper::GetMainFrame() { | 441 WebFrame* TranslateHelper::GetMainFrame() { |
| 727 WebView* web_view = render_view()->GetWebView(); | 442 WebView* web_view = render_view()->GetWebView(); |
| 728 | 443 |
| 729 // When the tab is going to be closed, the web_view can be NULL. | 444 // When the tab is going to be closed, the web_view can be NULL. |
| 730 if (!web_view) | 445 if (!web_view) |
| 731 return NULL; | 446 return NULL; |
| 732 | 447 |
| 733 return web_view->mainFrame(); | 448 return web_view->mainFrame(); |
| 734 } | 449 } |
| OLD | NEW |