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/common/localized_error.h" | 5 #include "chrome/common/localized_error.h" |
6 | 6 |
7 #include "base/i18n/rtl.h" | 7 #include "base/i18n/rtl.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/string16.h" | 9 #include "base/string16.h" |
10 #include "base/string_util.h" | |
10 #include "base/strings/string_number_conversions.h" | 11 #include "base/strings/string_number_conversions.h" |
11 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
12 #include "base/values.h" | 13 #include "base/values.h" |
13 #include "chrome/common/extensions/api/icons/icons_handler.h" | 14 #include "chrome/common/extensions/api/icons/icons_handler.h" |
14 #include "chrome/common/extensions/extension_constants.h" | 15 #include "chrome/common/extensions/extension_constants.h" |
15 #include "chrome/common/extensions/extension_icon_set.h" | 16 #include "chrome/common/extensions/extension_icon_set.h" |
16 #include "chrome/common/extensions/extension_set.h" | 17 #include "chrome/common/extensions/extension_set.h" |
17 #include "googleurl/src/gurl.h" | 18 #include "googleurl/src/gurl.h" |
18 #include "grit/chromium_strings.h" | 19 #include "grit/chromium_strings.h" |
19 #include "grit/generated_resources.h" | 20 #include "grit/generated_resources.h" |
20 #include "net/base/escape.h" | 21 #include "net/base/escape.h" |
21 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
22 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" | 23 #include "third_party/WebKit/Source/Platform/chromium/public/WebURLError.h" |
23 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
25 #include "ui/webui/web_ui_util.h" | |
24 #include "webkit/glue/webkit_glue.h" | 26 #include "webkit/glue/webkit_glue.h" |
25 | 27 |
26 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
27 #include "base/win/windows_version.h" | 29 #include "base/win/windows_version.h" |
28 #endif | 30 #endif |
29 | 31 |
30 using WebKit::WebURLError; | 32 using WebKit::WebURLError; |
31 | 33 |
34 // Some error pages have no details. | |
35 #define IDS_ERRORPAGES_DETAILS_NULL 0 | |
Nico
2013/03/26 17:56:31
const int?
Also, since this is not a real string
mmenke
2013/03/26 19:22:36
Done.
| |
36 | |
32 namespace { | 37 namespace { |
33 | 38 |
34 static const char kRedirectLoopLearnMoreUrl[] = | 39 static const char kRedirectLoopLearnMoreUrl[] = |
35 "https://www.google.com/support/chrome/bin/answer.py?answer=95626"; | 40 "https://www.google.com/support/chrome/bin/answer.py?answer=95626"; |
36 static const char kWeakDHKeyLearnMoreUrl[] = | 41 static const char kWeakDHKeyLearnMoreUrl[] = |
37 "http://sites.google.com/a/chromium.org/dev/" | 42 "http://sites.google.com/a/chromium.org/dev/" |
38 "err_ssl_weak_server_ephemeral_dh_key"; | 43 "err_ssl_weak_server_ephemeral_dh_key"; |
39 #if defined(OS_CHROMEOS) | 44 #if defined(OS_CHROMEOS) |
40 static const char kAppWarningLearnMoreUrl[] = | 45 static const char kAppWarningLearnMoreUrl[] = |
41 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html" | 46 "chrome-extension://honijodknafkokifofgiaalefdiedpko/main.html" |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
343 }, | 348 }, |
344 {505, | 349 {505, |
345 IDS_ERRORPAGES_TITLE_LOAD_FAILED, | 350 IDS_ERRORPAGES_TITLE_LOAD_FAILED, |
346 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR, | 351 IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR, |
347 IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE, | 352 IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE, |
348 IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED, | 353 IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED, |
349 SUGGEST_NONE, | 354 SUGGEST_NONE, |
350 }, | 355 }, |
351 }; | 356 }; |
352 | 357 |
353 const char* HttpErrorToString(int status_code) { | |
354 switch (status_code) { | |
355 case 403: | |
356 return "Forbidden"; | |
357 case 410: | |
358 return "Gone"; | |
359 case 500: | |
360 return "Internal Server Error"; | |
361 case 501: | |
362 return "Not Implemented"; | |
363 case 502: | |
364 return "Bad Gateway"; | |
365 case 503: | |
366 return "Service Unavailable"; | |
367 case 504: | |
368 return "Gateway Timeout"; | |
369 case 505: | |
370 return "HTTP Version Not Supported"; | |
371 default: | |
372 return ""; | |
373 } | |
374 } | |
375 | |
376 string16 GetErrorDetailsString(const std::string& error_domain, | |
377 int error_code, | |
378 const string16& details) { | |
379 int error_page_template; | |
380 const char* error_string; | |
381 if (error_domain == net::kErrorDomain) { | |
382 error_page_template = IDS_ERRORPAGES_DETAILS_TEMPLATE; | |
383 error_string = net::ErrorToString(error_code); | |
384 DCHECK(error_code < 0); // Net error codes are negative. | |
385 error_code = -error_code; | |
386 } else if (error_domain == LocalizedError::kHttpErrorDomain) { | |
387 error_page_template = IDS_ERRORPAGES_HTTP_DETAILS_TEMPLATE; | |
388 error_string = HttpErrorToString(error_code); | |
389 } else { | |
390 NOTREACHED(); | |
391 return string16(); | |
392 } | |
393 return l10n_util::GetStringFUTF16( | |
394 error_page_template, | |
395 base::IntToString16(error_code), | |
396 ASCIIToUTF16(error_string), | |
397 details); | |
398 } | |
399 | |
400 const LocalizedErrorMap* FindErrorMapInArray(const LocalizedErrorMap* maps, | 358 const LocalizedErrorMap* FindErrorMapInArray(const LocalizedErrorMap* maps, |
401 size_t num_maps, | 359 size_t num_maps, |
402 int error_code) { | 360 int error_code) { |
403 for (size_t i = 0; i < num_maps; ++i) { | 361 for (size_t i = 0; i < num_maps; ++i) { |
404 if (maps[i].error_code == error_code) | 362 if (maps[i].error_code == error_code) |
405 return &maps[i]; | 363 return &maps[i]; |
406 } | 364 } |
407 return NULL; | 365 return NULL; |
408 } | 366 } |
409 | 367 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
444 return standard_menu_items_text; | 402 return standard_menu_items_text; |
445 } | 403 } |
446 | 404 |
447 } // namespace | 405 } // namespace |
448 | 406 |
449 const char LocalizedError::kHttpErrorDomain[] = "http"; | 407 const char LocalizedError::kHttpErrorDomain[] = "http"; |
450 | 408 |
451 void LocalizedError::GetStrings(const WebKit::WebURLError& error, | 409 void LocalizedError::GetStrings(const WebKit::WebURLError& error, |
452 DictionaryValue* error_strings, | 410 DictionaryValue* error_strings, |
453 const std::string& locale) { | 411 const std::string& locale) { |
454 bool rtl = LocaleIsRTL(); | 412 webui::SetFontAndTextDirection(error_strings); |
455 error_strings->SetString("textdirection", rtl ? "rtl" : "ltr"); | 413 std::string text_direction; |
414 error_strings->GetString("&textdirection", &text_direction); | |
415 bool rtl = (text_direction == "rtl"); | |
456 | 416 |
457 // Grab the strings and settings that depend on the error type. Init | 417 // Grab the strings and settings that depend on the error type. Init |
458 // options with default values. | 418 // options with default values. |
459 LocalizedErrorMap options = { | 419 LocalizedErrorMap options = { |
460 0, | 420 0, |
461 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, | 421 IDS_ERRORPAGES_TITLE_NOT_AVAILABLE, |
462 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, | 422 IDS_ERRORPAGES_HEADING_NOT_AVAILABLE, |
463 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE, | 423 IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE, |
464 IDS_ERRORPAGES_DETAILS_UNKNOWN, | 424 IDS_ERRORPAGES_DETAILS_NULL, |
465 SUGGEST_NONE, | 425 SUGGEST_NONE, |
466 }; | 426 }; |
467 | 427 |
468 const std::string error_domain = error.domain.utf8(); | 428 const std::string error_domain = error.domain.utf8(); |
469 int error_code = error.reason; | 429 int error_code = error.reason; |
470 const LocalizedErrorMap* error_map = | 430 const LocalizedErrorMap* error_map = |
471 LookupErrorMap(error_domain, error_code); | 431 LookupErrorMap(error_domain, error_code); |
472 if (error_map) | 432 if (error_map) |
473 options = *error_map; | 433 options = *error_map; |
474 | 434 |
475 if (options.suggestions != SUGGEST_NONE) { | |
476 error_strings->SetString( | |
477 "suggestionsHeading", | |
478 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HEADING)); | |
479 } | |
480 | |
481 const GURL failed_url = error.unreachableURL; | 435 const GURL failed_url = error.unreachableURL; |
482 | 436 |
483 // If we got "access denied" but the url was a file URL, then we say it was a | 437 // If we got "access denied" but the url was a file URL, then we say it was a |
484 // file instead of just using the "not available" default message. Just adding | 438 // file instead of just using the "not available" default message. Just adding |
485 // ERR_ACCESS_DENIED to the map isn't sufficient, since that message may be | 439 // ERR_ACCESS_DENIED to the map isn't sufficient, since that message may be |
486 // generated by some OSs when the operation doesn't involve a file URL. | 440 // generated by some OSs when the operation doesn't involve a file URL. |
487 if (error_domain == net::kErrorDomain && | 441 if (error_domain == net::kErrorDomain && |
488 error_code == net::ERR_ACCESS_DENIED && | 442 error_code == net::ERR_ACCESS_DENIED && |
489 failed_url.scheme() == "file") { | 443 failed_url.scheme() == "file") { |
490 options.title_resource_id = IDS_ERRORPAGES_TITLE_ACCESS_DENIED; | 444 options.title_resource_id = IDS_ERRORPAGES_TITLE_ACCESS_DENIED; |
491 options.heading_resource_id = IDS_ERRORPAGES_HEADING_FILE_ACCESS_DENIED; | 445 options.heading_resource_id = IDS_ERRORPAGES_HEADING_FILE_ACCESS_DENIED; |
492 options.summary_resource_id = IDS_ERRORPAGES_SUMMARY_FILE_ACCESS_DENIED; | 446 options.summary_resource_id = IDS_ERRORPAGES_SUMMARY_FILE_ACCESS_DENIED; |
493 options.details_resource_id = IDS_ERRORPAGES_DETAILS_FILE_ACCESS_DENIED; | 447 options.details_resource_id = IDS_ERRORPAGES_DETAILS_FILE_ACCESS_DENIED; |
494 options.suggestions = SUGGEST_NONE; | 448 options.suggestions = SUGGEST_NONE; |
495 } | 449 } |
496 | 450 |
451 // If there are any suggestions other than reload, populate the suggestion | |
452 // heading (reload has a button, rather than a suggestion in the list). | |
453 if ((options.suggestions & ~SUGGEST_RELOAD) != SUGGEST_NONE) { | |
454 error_strings->SetString( | |
455 "suggestionsHeading", | |
456 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HEADING)); | |
457 } | |
458 | |
497 string16 failed_url_string(UTF8ToUTF16(failed_url.spec())); | 459 string16 failed_url_string(UTF8ToUTF16(failed_url.spec())); |
498 // URLs are always LTR. | 460 // URLs are always LTR. |
499 if (rtl) | 461 if (rtl) |
500 base::i18n::WrapStringWithLTRFormatting(&failed_url_string); | 462 base::i18n::WrapStringWithLTRFormatting(&failed_url_string); |
501 error_strings->SetString("title", | 463 error_strings->SetString("title", |
502 l10n_util::GetStringFUTF16(options.title_resource_id, failed_url_string)); | 464 l10n_util::GetStringFUTF16(options.title_resource_id, failed_url_string)); |
503 error_strings->SetString("heading", | 465 error_strings->SetString("heading", |
504 l10n_util::GetStringUTF16(options.heading_resource_id)); | 466 l10n_util::GetStringUTF16(options.heading_resource_id)); |
505 | 467 |
506 DictionaryValue* summary = new DictionaryValue; | 468 DictionaryValue* summary = new DictionaryValue; |
507 summary->SetString("msg", | 469 summary->SetString("msg", |
508 l10n_util::GetStringUTF16(options.summary_resource_id)); | 470 l10n_util::GetStringUTF16(options.summary_resource_id)); |
509 // TODO(tc): We want the unicode url and host here since they're being | 471 // TODO(tc): We want the unicode url and host here since they're being |
510 // displayed. | 472 // displayed. |
511 summary->SetString("failedUrl", failed_url_string); | 473 summary->SetString("failedUrl", failed_url_string); |
512 summary->SetString("hostName", failed_url.host()); | 474 summary->SetString("hostName", failed_url.host()); |
513 summary->SetString("productName", | 475 summary->SetString("productName", |
514 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); | 476 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); |
477 | |
478 error_strings->SetString( | |
479 "more", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_MORE)); | |
480 error_strings->SetString( | |
481 "less", l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_LESS)); | |
515 error_strings->Set("summary", summary); | 482 error_strings->Set("summary", summary); |
516 | 483 |
517 string16 details = l10n_util::GetStringUTF16(options.details_resource_id); | 484 if (options.details_resource_id != IDS_ERRORPAGES_DETAILS_NULL) { |
518 error_strings->SetString("details", | 485 error_strings->SetString( |
519 GetErrorDetailsString(error_domain, error_code, details)); | 486 "errorDetails", l10n_util::GetStringUTF16(options.details_resource_id)); |
487 } | |
488 | |
489 string16 error_string; | |
490 if (error_domain == net::kErrorDomain) { | |
491 // Non-internationalized error string, for debugging Chrome itself. | |
492 std::string ascii_error_string = net::ErrorToString(error_code); | |
493 // Remove the leading "net::" from the returned string. | |
494 RemoveChars(ascii_error_string, "net:", &ascii_error_string); | |
495 error_string = ASCIIToUTF16(ascii_error_string); | |
496 } else { | |
497 DCHECK_EQ(LocalizedError::kHttpErrorDomain, error_domain); | |
498 error_string = base::IntToString16(error_code); | |
499 } | |
500 error_strings->SetString("errorCode", | |
501 l10n_util::GetStringFUTF16(IDS_ERRORPAGES_ERROR_CODE, error_string)); | |
520 | 502 |
521 // Platform specific instructions for diagnosing network issues on OSX and | 503 // Platform specific instructions for diagnosing network issues on OSX and |
522 // Windows. | 504 // Windows. |
523 #if defined(OS_MACOSX) || defined(OS_WIN) | 505 #if defined(OS_MACOSX) || defined(OS_WIN) |
524 if (error_domain == net::kErrorDomain && | 506 if (error_domain == net::kErrorDomain && |
525 error_code == net::ERR_INTERNET_DISCONNECTED) { | 507 error_code == net::ERR_INTERNET_DISCONNECTED) { |
526 int platform_string_id = | 508 int platform_string_id = |
527 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM; | 509 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM; |
528 #if defined(OS_WIN) | 510 #if defined(OS_WIN) |
529 // Different versions of Windows have different instructions. | 511 // Different versions of Windows have different instructions. |
(...skipping 12 matching lines...) Expand all Loading... | |
542 // dependent portion of the summary section. | 524 // dependent portion of the summary section. |
543 summary->SetString("msg", | 525 summary->SetString("msg", |
544 l10n_util::GetStringFUTF16( | 526 l10n_util::GetStringFUTF16( |
545 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_INSTRUCTIONS_TEMPLATE, | 527 IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_INSTRUCTIONS_TEMPLATE, |
546 l10n_util::GetStringUTF16(options.summary_resource_id), | 528 l10n_util::GetStringUTF16(options.summary_resource_id), |
547 l10n_util::GetStringUTF16(platform_string_id))); | 529 l10n_util::GetStringUTF16(platform_string_id))); |
548 } | 530 } |
549 #endif // defined(OS_MACOSX) || defined(OS_WIN) | 531 #endif // defined(OS_MACOSX) || defined(OS_WIN) |
550 | 532 |
551 if (options.suggestions & SUGGEST_RELOAD) { | 533 if (options.suggestions & SUGGEST_RELOAD) { |
552 DictionaryValue* suggest_reload = new DictionaryValue; | 534 DictionaryValue* reload_button = new DictionaryValue; |
553 suggest_reload->SetString("msg", | 535 reload_button->SetString("msg", |
554 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_RELOAD)); | 536 l10n_util::GetStringUTF16(IDS_ERRORPAGES_BUTTON_RELOAD)); |
555 suggest_reload->SetString("reloadUrl", failed_url_string); | 537 reload_button->SetString("reloadUrl", failed_url_string); |
556 error_strings->Set("suggestionsReload", suggest_reload); | 538 error_strings->Set("reload", reload_button); |
557 } | 539 } |
558 | 540 |
559 if (options.suggestions & SUGGEST_HOSTNAME) { | 541 if (options.suggestions & SUGGEST_HOSTNAME) { |
560 // Only show the "Go to hostname" suggestion if the failed_url has a path. | 542 // Only show the "Go to hostname" suggestion if the failed_url has a path. |
561 if (std::string() == failed_url.path()) { | 543 if (std::string() == failed_url.path()) { |
562 DictionaryValue* suggest_home_page = new DictionaryValue; | 544 DictionaryValue* suggest_home_page = new DictionaryValue; |
563 suggest_home_page->SetString("suggestionsHomepageMsg", | 545 suggest_home_page->SetString("suggestionsHomepageMsg", |
564 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HOMEPAGE)); | 546 l10n_util::GetStringUTF16(IDS_ERRORPAGES_SUGGESTION_HOMEPAGE)); |
565 string16 homepage(ASCIIToUTF16(failed_url.GetWithEmptyPath().spec())); | 547 string16 homepage(ASCIIToUTF16(failed_url.GetWithEmptyPath().spec())); |
566 // URLs are always LTR. | 548 // URLs are always LTR. |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
756 #if defined(OS_CHROMEOS) | 738 #if defined(OS_CHROMEOS) |
757 GURL learn_more_url(kAppWarningLearnMoreUrl); | 739 GURL learn_more_url(kAppWarningLearnMoreUrl); |
758 DictionaryValue* suggest_learn_more = new DictionaryValue(); | 740 DictionaryValue* suggest_learn_more = new DictionaryValue(); |
759 suggest_learn_more->SetString("msg", | 741 suggest_learn_more->SetString("msg", |
760 l10n_util::GetStringUTF16( | 742 l10n_util::GetStringUTF16( |
761 IDS_ERRORPAGES_SUGGESTION_LEARNMORE)); | 743 IDS_ERRORPAGES_SUGGESTION_LEARNMORE)); |
762 suggest_learn_more->SetString("learnMoreUrl", learn_more_url.spec()); | 744 suggest_learn_more->SetString("learnMoreUrl", learn_more_url.spec()); |
763 error_strings->Set("suggestionsLearnMore", suggest_learn_more); | 745 error_strings->Set("suggestionsLearnMore", suggest_learn_more); |
764 #endif // defined(OS_CHROMEOS) | 746 #endif // defined(OS_CHROMEOS) |
765 } | 747 } |
OLD | NEW |