| 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/browser/translate/translate_infobar_delegate.h" | 5 #include "chrome/browser/translate/translate_infobar_delegate.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/i18n/string_compare.h" | 9 #include "base/i18n/string_compare.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| 11 #include "base/prefs/pref_service.h" | 11 #include "base/prefs/pref_service.h" |
| 12 #include "chrome/browser/browser_process.h" | 12 #include "chrome/browser/browser_process.h" |
| 13 #include "chrome/browser/infobars/infobar_service.h" | 13 #include "chrome/browser/infobars/infobar_service.h" |
| 14 #include "chrome/browser/profiles/profile.h" | 14 #include "chrome/browser/profiles/profile.h" |
| 15 #include "chrome/browser/translate/translate_accept_languages.h" | 15 #include "chrome/browser/translate/translate_accept_languages.h" |
| 16 #include "chrome/browser/translate/translate_manager.h" | 16 #include "chrome/browser/translate/translate_manager.h" |
| 17 #include "chrome/browser/translate/translate_tab_helper.h" | 17 #include "chrome/browser/translate/translate_tab_helper.h" |
| 18 #include "content/public/browser/navigation_details.h" | 18 #include "content/public/browser/navigation_details.h" |
| 19 #include "content/public/browser/navigation_entry.h" | 19 #include "content/public/browser/navigation_entry.h" |
| 20 #include "content/public/browser/web_contents.h" | 20 #include "content/public/browser/web_contents.h" |
| 21 #include "grit/generated_resources.h" | 21 #include "grit/generated_resources.h" |
| 22 #include "grit/theme_resources.h" | 22 #include "grit/theme_resources.h" |
| 23 #include "third_party/icu/source/i18n/unicode/coll.h" | 23 #include "third_party/icu/source/i18n/unicode/coll.h" |
| 24 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
| 25 | 25 |
| 26 using content::NavigationEntry; | 26 using content::NavigationEntry; |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 const char kDeclineTranslate[] = "Translate.DeclineTranslate"; | |
| 31 const char kCloseInfobar[] = "Translate.DeclineTranslateCloseInfobar"; | 30 const char kCloseInfobar[] = "Translate.DeclineTranslateCloseInfobar"; |
| 32 const char kRevertTranslation[] = "Translate.RevertTranslation"; | |
| 33 const char kShowErrorInfobar[] = "Translate.ShowErrorInfobar"; | 31 const char kShowErrorInfobar[] = "Translate.ShowErrorInfobar"; |
| 34 const char kPerformTranslate[] = "Translate.Translate"; | |
| 35 const char kNeverTranslateLang[] = "Translate.NeverTranslateLang"; | |
| 36 const char kNeverTranslateSite[] = "Translate.NeverTranslateSite"; | |
| 37 const char kAlwaysTranslateLang[] = "Translate.AlwaysTranslateLang"; | |
| 38 | 32 |
| 39 } // namespace | 33 } // namespace |
| 40 | 34 |
| 41 // static | 35 const size_t TranslateInfoBarDelegate::kNoIndex = TranslateUIDelegate::kNoIndex; |
| 42 const size_t TranslateInfoBarDelegate::kNoIndex = static_cast<size_t>(-1); | |
| 43 | 36 |
| 44 TranslateInfoBarDelegate::~TranslateInfoBarDelegate() { | 37 TranslateInfoBarDelegate::~TranslateInfoBarDelegate() { |
| 45 } | 38 } |
| 46 | 39 |
| 47 // static | 40 // static |
| 48 void TranslateInfoBarDelegate::Create( | 41 void TranslateInfoBarDelegate::Create( |
| 49 bool replace_existing_infobar, | 42 bool replace_existing_infobar, |
| 50 InfoBarService* infobar_service, | 43 InfoBarService* infobar_service, |
| 51 Type infobar_type, | 44 Type infobar_type, |
| 52 const std::string& original_language, | 45 const std::string& original_language, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 if (!old_delegate) { | 90 if (!old_delegate) { |
| 98 infobar_service->AddInfoBar(infobar.PassAs<InfoBarDelegate>()); | 91 infobar_service->AddInfoBar(infobar.PassAs<InfoBarDelegate>()); |
| 99 } else { | 92 } else { |
| 100 DCHECK(replace_existing_infobar); | 93 DCHECK(replace_existing_infobar); |
| 101 infobar_service->ReplaceInfoBar(old_delegate, | 94 infobar_service->ReplaceInfoBar(old_delegate, |
| 102 infobar.PassAs<InfoBarDelegate>()); | 95 infobar.PassAs<InfoBarDelegate>()); |
| 103 } | 96 } |
| 104 } | 97 } |
| 105 | 98 |
| 106 void TranslateInfoBarDelegate::Translate() { | 99 void TranslateInfoBarDelegate::Translate() { |
| 107 if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) { | 100 ui_delegate_.Translate(); |
| 108 prefs_.ResetTranslationDeniedCount(original_language_code()); | |
| 109 prefs_.IncrementTranslationAcceptedCount(original_language_code()); | |
| 110 } | |
| 111 | |
| 112 TranslateManager::GetInstance()->TranslatePage(web_contents(), | |
| 113 original_language_code(), | |
| 114 target_language_code()); | |
| 115 | |
| 116 UMA_HISTOGRAM_BOOLEAN(kPerformTranslate, true); | |
| 117 } | 101 } |
| 118 | 102 |
| 119 void TranslateInfoBarDelegate::RevertTranslation() { | 103 void TranslateInfoBarDelegate::RevertTranslation() { |
| 120 TranslateManager::GetInstance()->RevertTranslation(web_contents()); | 104 ui_delegate_.RevertTranslation(); |
| 121 RemoveSelf(); | 105 RemoveSelf(); |
| 122 | |
| 123 UMA_HISTOGRAM_BOOLEAN(kRevertTranslation, true); | |
| 124 } | 106 } |
| 125 | 107 |
| 126 void TranslateInfoBarDelegate::ReportLanguageDetectionError() { | 108 void TranslateInfoBarDelegate::ReportLanguageDetectionError() { |
| 127 TranslateManager::GetInstance()->ReportLanguageDetectionError( | 109 TranslateManager::GetInstance()->ReportLanguageDetectionError( |
| 128 web_contents()); | 110 web_contents()); |
| 129 } | 111 } |
| 130 | 112 |
| 131 void TranslateInfoBarDelegate::TranslationDeclined() { | 113 void TranslateInfoBarDelegate::TranslationDeclined() { |
| 132 if (!web_contents()->GetBrowserContext()->IsOffTheRecord()) { | 114 ui_delegate_.TranslationDeclined(); |
| 133 prefs_.ResetTranslationAcceptedCount(original_language_code()); | |
| 134 prefs_.IncrementTranslationDeniedCount(original_language_code()); | |
| 135 } | |
| 136 | |
| 137 // Remember that the user declined the translation so as to prevent showing a | |
| 138 // translate infobar for that page again. (TranslateManager initiates | |
| 139 // translations when getting a LANGUAGE_DETERMINED from the page, which | |
| 140 // happens when a load stops. That could happen multiple times, including | |
| 141 // after the user already declined the translation.) | |
| 142 TranslateTabHelper::FromWebContents(web_contents())-> | |
| 143 language_state().set_translation_declined(true); | |
| 144 | |
| 145 UMA_HISTOGRAM_BOOLEAN(kDeclineTranslate, true); | |
| 146 } | 115 } |
| 147 | 116 |
| 148 bool TranslateInfoBarDelegate::IsTranslatableLanguageByPrefs() { | 117 bool TranslateInfoBarDelegate::IsTranslatableLanguageByPrefs() { |
| 149 Profile* profile = | 118 Profile* profile = |
| 150 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); | 119 Profile::FromBrowserContext(web_contents()->GetBrowserContext()); |
| 151 Profile* original_profile = profile->GetOriginalProfile(); | 120 Profile* original_profile = profile->GetOriginalProfile(); |
| 152 return TranslatePrefs::CanTranslateLanguage(original_profile, | 121 return TranslatePrefs::CanTranslateLanguage(original_profile, |
| 153 original_language_code()); | 122 original_language_code()); |
| 154 } | 123 } |
| 155 | 124 |
| 156 void TranslateInfoBarDelegate::ToggleTranslatableLanguageByPrefs() { | 125 void TranslateInfoBarDelegate::ToggleTranslatableLanguageByPrefs() { |
| 157 const std::string& original_lang = original_language_code(); | 126 if (ui_delegate_.IsLanguageBlocked()) { |
| 158 if (prefs_.IsBlockedLanguage(original_lang)) { | 127 ui_delegate_.SetLanguageBlocked(false); |
| 159 prefs_.UnblockLanguage(original_lang); | |
| 160 } else { | 128 } else { |
| 161 prefs_.BlockLanguage(original_lang); | 129 ui_delegate_.SetLanguageBlocked(true); |
| 162 RemoveSelf(); | 130 RemoveSelf(); |
| 163 } | 131 } |
| 164 | |
| 165 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateLang, true); | |
| 166 } | 132 } |
| 167 | 133 |
| 168 bool TranslateInfoBarDelegate::IsSiteBlacklisted() { | 134 bool TranslateInfoBarDelegate::IsSiteBlacklisted() { |
| 169 std::string host = GetPageHost(); | 135 return ui_delegate_.IsSiteBlacklisted(); |
| 170 return !host.empty() && prefs_.IsSiteBlacklisted(host); | |
| 171 } | 136 } |
| 172 | 137 |
| 173 void TranslateInfoBarDelegate::ToggleSiteBlacklist() { | 138 void TranslateInfoBarDelegate::ToggleSiteBlacklist() { |
| 174 std::string host = GetPageHost(); | 139 if (ui_delegate_.IsSiteBlacklisted()) { |
| 175 if (host.empty()) | 140 ui_delegate_.SetSiteBlacklist(false); |
| 176 return; | |
| 177 | |
| 178 if (prefs_.IsSiteBlacklisted(host)) { | |
| 179 prefs_.RemoveSiteFromBlacklist(host); | |
| 180 } else { | 141 } else { |
| 181 prefs_.BlacklistSite(host); | 142 ui_delegate_.SetSiteBlacklist(true); |
| 182 RemoveSelf(); | 143 RemoveSelf(); |
| 183 } | 144 } |
| 184 | |
| 185 UMA_HISTOGRAM_BOOLEAN(kNeverTranslateSite, true); | |
| 186 } | 145 } |
| 187 | 146 |
| 188 bool TranslateInfoBarDelegate::ShouldAlwaysTranslate() { | 147 bool TranslateInfoBarDelegate::ShouldAlwaysTranslate() { |
| 189 return prefs_.IsLanguagePairWhitelisted(original_language_code(), | 148 return ui_delegate_.ShouldAlwaysTranslate(); |
| 190 target_language_code()); | |
| 191 } | 149 } |
| 192 | 150 |
| 193 void TranslateInfoBarDelegate::ToggleAlwaysTranslate() { | 151 void TranslateInfoBarDelegate::ToggleAlwaysTranslate() { |
| 194 const std::string& original_lang = original_language_code(); | 152 ui_delegate_.SetAlwaysTranslate(!ui_delegate_.ShouldAlwaysTranslate()); |
| 195 const std::string& target_lang = target_language_code(); | |
| 196 if (prefs_.IsLanguagePairWhitelisted(original_lang, target_lang)) | |
| 197 prefs_.RemoveLanguagePairFromWhitelist(original_lang, target_lang); | |
| 198 else | |
| 199 prefs_.WhitelistLanguagePair(original_lang, target_lang); | |
| 200 | |
| 201 UMA_HISTOGRAM_BOOLEAN(kAlwaysTranslateLang, true); | |
| 202 } | 153 } |
| 203 | 154 |
| 204 void TranslateInfoBarDelegate::AlwaysTranslatePageLanguage() { | 155 void TranslateInfoBarDelegate::AlwaysTranslatePageLanguage() { |
| 205 const std::string& original_lang = original_language_code(); | 156 DCHECK(!ui_delegate_.ShouldAlwaysTranslate()); |
| 206 const std::string& target_lang = target_language_code(); | 157 ui_delegate_.SetAlwaysTranslate(true); |
| 207 DCHECK(!prefs_.IsLanguagePairWhitelisted(original_lang, target_lang)); | |
| 208 prefs_.WhitelistLanguagePair(original_lang, target_lang); | |
| 209 Translate(); | 158 Translate(); |
| 210 } | 159 } |
| 211 | 160 |
| 212 void TranslateInfoBarDelegate::NeverTranslatePageLanguage() { | 161 void TranslateInfoBarDelegate::NeverTranslatePageLanguage() { |
| 213 std::string original_lang = original_language_code(); | 162 DCHECK(!ui_delegate_.IsLanguageBlocked()); |
| 214 DCHECK(!prefs_.IsBlockedLanguage(original_lang)); | 163 ui_delegate_.SetLanguageBlocked(true); |
| 215 prefs_.BlockLanguage(original_lang); | |
| 216 RemoveSelf(); | 164 RemoveSelf(); |
| 217 } | 165 } |
| 218 | 166 |
| 219 string16 TranslateInfoBarDelegate::GetMessageInfoBarText() { | 167 string16 TranslateInfoBarDelegate::GetMessageInfoBarText() { |
| 220 if (infobar_type_ == TRANSLATING) { | 168 if (infobar_type_ == TRANSLATING) { |
| 169 string16 target_language_name = language_name_at(target_language_index()); |
| 221 return l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_TRANSLATING_TO, | 170 return l10n_util::GetStringFUTF16(IDS_TRANSLATE_INFOBAR_TRANSLATING_TO, |
| 222 language_name_at(target_language_index_)); | 171 target_language_name); |
| 223 } | 172 } |
| 224 | 173 |
| 225 DCHECK_EQ(TRANSLATION_ERROR, infobar_type_); | 174 DCHECK_EQ(TRANSLATION_ERROR, infobar_type_); |
| 226 UMA_HISTOGRAM_ENUMERATION(kShowErrorInfobar, | 175 UMA_HISTOGRAM_ENUMERATION(kShowErrorInfobar, |
| 227 error_type_, | 176 error_type_, |
| 228 TranslateErrors::TRANSLATE_ERROR_MAX); | 177 TranslateErrors::TRANSLATE_ERROR_MAX); |
| 229 switch (error_type_) { | 178 switch (error_type_) { |
| 230 case TranslateErrors::NETWORK: | 179 case TranslateErrors::NETWORK: |
| 231 return l10n_util::GetStringUTF16( | 180 return l10n_util::GetStringUTF16( |
| 232 IDS_TRANSLATE_INFOBAR_ERROR_CANT_CONNECT); | 181 IDS_TRANSLATE_INFOBAR_ERROR_CANT_CONNECT); |
| 233 case TranslateErrors::INITIALIZATION_ERROR: | 182 case TranslateErrors::INITIALIZATION_ERROR: |
| 234 case TranslateErrors::TRANSLATION_ERROR: | 183 case TranslateErrors::TRANSLATION_ERROR: |
| 235 return l10n_util::GetStringUTF16( | 184 return l10n_util::GetStringUTF16( |
| 236 IDS_TRANSLATE_INFOBAR_ERROR_CANT_TRANSLATE); | 185 IDS_TRANSLATE_INFOBAR_ERROR_CANT_TRANSLATE); |
| 237 case TranslateErrors::UNKNOWN_LANGUAGE: | 186 case TranslateErrors::UNKNOWN_LANGUAGE: |
| 238 return l10n_util::GetStringUTF16( | 187 return l10n_util::GetStringUTF16( |
| 239 IDS_TRANSLATE_INFOBAR_UNKNOWN_PAGE_LANGUAGE); | 188 IDS_TRANSLATE_INFOBAR_UNKNOWN_PAGE_LANGUAGE); |
| 240 case TranslateErrors::UNSUPPORTED_LANGUAGE: | 189 case TranslateErrors::UNSUPPORTED_LANGUAGE: |
| 241 return l10n_util::GetStringFUTF16( | 190 return l10n_util::GetStringFUTF16( |
| 242 IDS_TRANSLATE_INFOBAR_UNSUPPORTED_PAGE_LANGUAGE, | 191 IDS_TRANSLATE_INFOBAR_UNSUPPORTED_PAGE_LANGUAGE, |
| 243 language_name_at(target_language_index_)); | 192 language_name_at(target_language_index())); |
| 244 case TranslateErrors::IDENTICAL_LANGUAGES: | 193 case TranslateErrors::IDENTICAL_LANGUAGES: |
| 245 return l10n_util::GetStringFUTF16( | 194 return l10n_util::GetStringFUTF16( |
| 246 IDS_TRANSLATE_INFOBAR_ERROR_SAME_LANGUAGE, | 195 IDS_TRANSLATE_INFOBAR_ERROR_SAME_LANGUAGE, |
| 247 language_name_at(target_language_index_)); | 196 language_name_at(target_language_index())); |
| 248 default: | 197 default: |
| 249 NOTREACHED(); | 198 NOTREACHED(); |
| 250 return string16(); | 199 return string16(); |
| 251 } | 200 } |
| 252 } | 201 } |
| 253 | 202 |
| 254 string16 TranslateInfoBarDelegate::GetMessageInfoBarButtonText() { | 203 string16 TranslateInfoBarDelegate::GetMessageInfoBarButtonText() { |
| 255 if (infobar_type_ != TRANSLATION_ERROR) { | 204 if (infobar_type_ != TRANSLATION_ERROR) { |
| 256 DCHECK_EQ(TRANSLATING, infobar_type_); | 205 DCHECK_EQ(TRANSLATING, infobar_type_); |
| 257 } else if ((error_type_ != TranslateErrors::IDENTICAL_LANGUAGES) && | 206 } else if ((error_type_ != TranslateErrors::IDENTICAL_LANGUAGES) && |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 Type infobar_type, | 287 Type infobar_type, |
| 339 TranslateInfoBarDelegate* old_delegate, | 288 TranslateInfoBarDelegate* old_delegate, |
| 340 const std::string& original_language, | 289 const std::string& original_language, |
| 341 const std::string& target_language, | 290 const std::string& target_language, |
| 342 TranslateErrors::Type error_type, | 291 TranslateErrors::Type error_type, |
| 343 PrefService* prefs, | 292 PrefService* prefs, |
| 344 ShortcutConfiguration shortcut_config) | 293 ShortcutConfiguration shortcut_config) |
| 345 : InfoBarDelegate(infobar_service), | 294 : InfoBarDelegate(infobar_service), |
| 346 infobar_type_(infobar_type), | 295 infobar_type_(infobar_type), |
| 347 background_animation_(NONE), | 296 background_animation_(NONE), |
| 348 original_language_index_(kNoIndex), | 297 ui_delegate_(web_contents(), original_language, target_language), |
| 349 initial_original_language_index_(kNoIndex), | |
| 350 target_language_index_(kNoIndex), | |
| 351 error_type_(error_type), | 298 error_type_(error_type), |
| 352 prefs_(prefs), | 299 prefs_(prefs), |
| 353 shortcut_config_(shortcut_config) { | 300 shortcut_config_(shortcut_config) { |
| 354 DCHECK_NE((infobar_type_ == TRANSLATION_ERROR), | 301 DCHECK_NE((infobar_type_ == TRANSLATION_ERROR), |
| 355 (error_type_ == TranslateErrors::NONE)); | 302 (error_type_ == TranslateErrors::NONE)); |
| 356 | 303 |
| 357 if (old_delegate && (old_delegate->is_error() != is_error())) | 304 if (old_delegate && (old_delegate->is_error() != is_error())) |
| 358 background_animation_ = is_error() ? NORMAL_TO_ERROR : ERROR_TO_NORMAL; | 305 background_animation_ = is_error() ? NORMAL_TO_ERROR : ERROR_TO_NORMAL; |
| 359 | |
| 360 std::vector<std::string> language_codes; | |
| 361 TranslateManager::GetSupportedLanguages(&language_codes); | |
| 362 | |
| 363 // Preparing for the alphabetical order in the locale. | |
| 364 UErrorCode error = U_ZERO_ERROR; | |
| 365 std::string locale = g_browser_process->GetApplicationLocale(); | |
| 366 icu::Locale loc(locale.c_str()); | |
| 367 scoped_ptr<icu::Collator> collator(icu::Collator::createInstance(loc, error)); | |
| 368 collator->setStrength(icu::Collator::PRIMARY); | |
| 369 | |
| 370 languages_.reserve(language_codes.size()); | |
| 371 for (std::vector<std::string>::const_iterator iter = language_codes.begin(); | |
| 372 iter != language_codes.end(); ++iter) { | |
| 373 std::string language_code = *iter; | |
| 374 | |
| 375 string16 language_name = GetLanguageDisplayableName(language_code); | |
| 376 // Insert the language in languages_ in alphabetical order. | |
| 377 std::vector<LanguageNamePair>::iterator iter2; | |
| 378 for (iter2 = languages_.begin(); iter2 != languages_.end(); ++iter2) { | |
| 379 if (base::i18n::CompareString16WithCollator(collator.get(), | |
| 380 language_name, iter2->second) == UCOL_LESS) { | |
| 381 break; | |
| 382 } | |
| 383 } | |
| 384 languages_.insert(iter2, LanguageNamePair(language_code, language_name)); | |
| 385 } | |
| 386 for (std::vector<LanguageNamePair>::const_iterator iter = languages_.begin(); | |
| 387 iter != languages_.end(); ++iter) { | |
| 388 std::string language_code = iter->first; | |
| 389 if (language_code == original_language) { | |
| 390 original_language_index_ = iter - languages_.begin(); | |
| 391 initial_original_language_index_ = original_language_index_; | |
| 392 } | |
| 393 if (language_code == target_language) | |
| 394 target_language_index_ = iter - languages_.begin(); | |
| 395 } | |
| 396 DCHECK_NE(kNoIndex, target_language_index_); | |
| 397 } | 306 } |
| 398 | 307 |
| 399 void TranslateInfoBarDelegate::InfoBarDismissed() { | 308 void TranslateInfoBarDelegate::InfoBarDismissed() { |
| 400 if (infobar_type_ != BEFORE_TRANSLATE) | 309 if (infobar_type_ != BEFORE_TRANSLATE) |
| 401 return; | 310 return; |
| 402 | 311 |
| 403 // The user closed the infobar without clicking the translate button. | 312 // The user closed the infobar without clicking the translate button. |
| 404 TranslationDeclined(); | 313 TranslationDeclined(); |
| 405 UMA_HISTOGRAM_BOOLEAN(kCloseInfobar, true); | 314 UMA_HISTOGRAM_BOOLEAN(kCloseInfobar, true); |
| 406 } | 315 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 420 if (!details.is_navigation_to_different_page() && !details.is_main_frame) | 329 if (!details.is_navigation_to_different_page() && !details.is_main_frame) |
| 421 return false; | 330 return false; |
| 422 | 331 |
| 423 return InfoBarDelegate::ShouldExpireInternal(details); | 332 return InfoBarDelegate::ShouldExpireInternal(details); |
| 424 } | 333 } |
| 425 | 334 |
| 426 TranslateInfoBarDelegate* | 335 TranslateInfoBarDelegate* |
| 427 TranslateInfoBarDelegate::AsTranslateInfoBarDelegate() { | 336 TranslateInfoBarDelegate::AsTranslateInfoBarDelegate() { |
| 428 return this; | 337 return this; |
| 429 } | 338 } |
| 430 | |
| 431 std::string TranslateInfoBarDelegate::GetPageHost() { | |
| 432 NavigationEntry* entry = web_contents()->GetController().GetActiveEntry(); | |
| 433 return entry ? entry->GetURL().HostNoBrackets() : std::string(); | |
| 434 } | |
| OLD | NEW |