| 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/search_engines/template_url.h" | 5 #include "chrome/browser/search_engines/template_url.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 const char* encoding, | 123 const char* encoding, |
| 124 bool is_in_query, | 124 bool is_in_query, |
| 125 base::string16* escaped_terms, | 125 base::string16* escaped_terms, |
| 126 base::string16* escaped_original_query) { | 126 base::string16* escaped_original_query) { |
| 127 DCHECK(escaped_terms); | 127 DCHECK(escaped_terms); |
| 128 DCHECK(escaped_original_query); | 128 DCHECK(escaped_original_query); |
| 129 std::string encoded_terms; | 129 std::string encoded_terms; |
| 130 if (!base::UTF16ToCodepage(terms, encoding, | 130 if (!base::UTF16ToCodepage(terms, encoding, |
| 131 base::OnStringConversionError::SKIP, &encoded_terms)) | 131 base::OnStringConversionError::SKIP, &encoded_terms)) |
| 132 return false; | 132 return false; |
| 133 *escaped_terms = UTF8ToUTF16(is_in_query ? | 133 *escaped_terms = base::UTF8ToUTF16(is_in_query ? |
| 134 net::EscapeQueryParamValue(encoded_terms, true) : | 134 net::EscapeQueryParamValue(encoded_terms, true) : |
| 135 net::EscapePath(encoded_terms)); | 135 net::EscapePath(encoded_terms)); |
| 136 if (original_query.empty()) | 136 if (original_query.empty()) |
| 137 return true; | 137 return true; |
| 138 std::string encoded_original_query; | 138 std::string encoded_original_query; |
| 139 if (!base::UTF16ToCodepage(original_query, encoding, | 139 if (!base::UTF16ToCodepage(original_query, encoding, |
| 140 base::OnStringConversionError::SKIP, &encoded_original_query)) | 140 base::OnStringConversionError::SKIP, &encoded_original_query)) |
| 141 return false; | 141 return false; |
| 142 *escaped_original_query = | 142 *escaped_original_query = base::UTF8ToUTF16( |
| 143 UTF8ToUTF16(net::EscapeQueryParamValue(encoded_original_query, true)); | 143 net::EscapeQueryParamValue(encoded_original_query, true)); |
| 144 return true; | 144 return true; |
| 145 } | 145 } |
| 146 | 146 |
| 147 // Extract query key and host given a list of parameters coming from the URL | 147 // Extract query key and host given a list of parameters coming from the URL |
| 148 // query or ref. | 148 // query or ref. |
| 149 std::string FindSearchTermsKey(const std::string& params) { | 149 std::string FindSearchTermsKey(const std::string& params) { |
| 150 if (params.empty()) | 150 if (params.empty()) |
| 151 return std::string(); | 151 return std::string(); |
| 152 url_parse::Component query, key, value; | 152 url_parse::Component query, key, value; |
| 153 query.len = static_cast<int>(params.size()); | 153 query.len = static_cast<int>(params.size()); |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 } | 372 } |
| 373 | 373 |
| 374 bool TemplateURLRef::IsValidUsingTermsData( | 374 bool TemplateURLRef::IsValidUsingTermsData( |
| 375 const SearchTermsData& search_terms_data) const { | 375 const SearchTermsData& search_terms_data) const { |
| 376 ParseIfNecessaryUsingTermsData(search_terms_data); | 376 ParseIfNecessaryUsingTermsData(search_terms_data); |
| 377 return valid_; | 377 return valid_; |
| 378 } | 378 } |
| 379 | 379 |
| 380 base::string16 TemplateURLRef::DisplayURL() const { | 380 base::string16 TemplateURLRef::DisplayURL() const { |
| 381 ParseIfNecessary(); | 381 ParseIfNecessary(); |
| 382 base::string16 result(UTF8ToUTF16(GetURL())); | 382 base::string16 result(base::UTF8ToUTF16(GetURL())); |
| 383 if (valid_ && !replacements_.empty()) { | 383 if (valid_ && !replacements_.empty()) { |
| 384 ReplaceSubstringsAfterOffset(&result, 0, | 384 ReplaceSubstringsAfterOffset(&result, 0, |
| 385 ASCIIToUTF16(kSearchTermsParameterFull), | 385 base::ASCIIToUTF16(kSearchTermsParameterFull), |
| 386 ASCIIToUTF16(kDisplaySearchTerms)); | 386 base::ASCIIToUTF16(kDisplaySearchTerms)); |
| 387 ReplaceSubstringsAfterOffset(&result, 0, | 387 ReplaceSubstringsAfterOffset(&result, 0, |
| 388 ASCIIToUTF16(kGoogleUnescapedSearchTermsParameterFull), | 388 base::ASCIIToUTF16(kGoogleUnescapedSearchTermsParameterFull), |
| 389 ASCIIToUTF16(kDisplayUnescapedSearchTerms)); | 389 base::ASCIIToUTF16(kDisplayUnescapedSearchTerms)); |
| 390 } | 390 } |
| 391 return result; | 391 return result; |
| 392 } | 392 } |
| 393 | 393 |
| 394 // static | 394 // static |
| 395 std::string TemplateURLRef::DisplayURLToURLRef( | 395 std::string TemplateURLRef::DisplayURLToURLRef( |
| 396 const base::string16& display_url) { | 396 const base::string16& display_url) { |
| 397 base::string16 result = display_url; | 397 base::string16 result = display_url; |
| 398 ReplaceSubstringsAfterOffset(&result, 0, ASCIIToUTF16(kDisplaySearchTerms), | 398 ReplaceSubstringsAfterOffset(&result, 0, |
| 399 ASCIIToUTF16(kSearchTermsParameterFull)); | 399 base::ASCIIToUTF16(kDisplaySearchTerms), |
| 400 base::ASCIIToUTF16(kSearchTermsParameterFull)); |
| 400 ReplaceSubstringsAfterOffset( | 401 ReplaceSubstringsAfterOffset( |
| 401 &result, 0, | 402 &result, 0, |
| 402 ASCIIToUTF16(kDisplayUnescapedSearchTerms), | 403 base::ASCIIToUTF16(kDisplayUnescapedSearchTerms), |
| 403 ASCIIToUTF16(kGoogleUnescapedSearchTermsParameterFull)); | 404 base::ASCIIToUTF16(kGoogleUnescapedSearchTermsParameterFull)); |
| 404 return UTF16ToUTF8(result); | 405 return base::UTF16ToUTF8(result); |
| 405 } | 406 } |
| 406 | 407 |
| 407 const std::string& TemplateURLRef::GetHost() const { | 408 const std::string& TemplateURLRef::GetHost() const { |
| 408 ParseIfNecessary(); | 409 ParseIfNecessary(); |
| 409 return host_; | 410 return host_; |
| 410 } | 411 } |
| 411 | 412 |
| 412 const std::string& TemplateURLRef::GetPath() const { | 413 const std::string& TemplateURLRef::GetPath() const { |
| 413 ParseIfNecessary(); | 414 ParseIfNecessary(); |
| 414 return path_; | 415 return path_; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 435 } | 436 } |
| 436 | 437 |
| 437 // Always fall back on UTF-8 if it works. | 438 // Always fall back on UTF-8 if it works. |
| 438 if (base::CodepageToUTF16(unescaped, base::kCodepageUTF8, | 439 if (base::CodepageToUTF16(unescaped, base::kCodepageUTF8, |
| 439 base::OnStringConversionError::FAIL, &result)) | 440 base::OnStringConversionError::FAIL, &result)) |
| 440 return result; | 441 return result; |
| 441 | 442 |
| 442 // When nothing worked, just use the escaped text. We have no idea what the | 443 // When nothing worked, just use the escaped text. We have no idea what the |
| 443 // encoding is. We need to substitute spaces for pluses ourselves since we're | 444 // encoding is. We need to substitute spaces for pluses ourselves since we're |
| 444 // not sending it through an unescaper. | 445 // not sending it through an unescaper. |
| 445 result = UTF8ToUTF16(term); | 446 result = base::UTF8ToUTF16(term); |
| 446 std::replace(result.begin(), result.end(), '+', ' '); | 447 std::replace(result.begin(), result.end(), '+', ' '); |
| 447 return result; | 448 return result; |
| 448 } | 449 } |
| 449 | 450 |
| 450 bool TemplateURLRef::HasGoogleBaseURLs() const { | 451 bool TemplateURLRef::HasGoogleBaseURLs() const { |
| 451 ParseIfNecessary(); | 452 ParseIfNecessary(); |
| 452 for (size_t i = 0; i < replacements_.size(); ++i) { | 453 for (size_t i = 0; i < replacements_.size(); ++i) { |
| 453 if ((replacements_[i].type == GOOGLE_BASE_URL) || | 454 if ((replacements_[i].type == GOOGLE_BASE_URL) || |
| 454 (replacements_[i].type == GOOGLE_BASE_SUGGEST_URL)) | 455 (replacements_[i].type == GOOGLE_BASE_SUGGEST_URL)) |
| 455 return true; | 456 return true; |
| (...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 *i, | 919 *i, |
| 919 &url); | 920 &url); |
| 920 } | 921 } |
| 921 break; | 922 break; |
| 922 | 923 |
| 923 case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION: | 924 case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION: |
| 924 DCHECK(!i->is_post_param); | 925 DCHECK(!i->is_post_param); |
| 925 if (search_terms_args.accepted_suggestion >= 0 || | 926 if (search_terms_args.accepted_suggestion >= 0 || |
| 926 !search_terms_args.assisted_query_stats.empty()) { | 927 !search_terms_args.assisted_query_stats.empty()) { |
| 927 HandleReplacement( | 928 HandleReplacement( |
| 928 "oq", UTF16ToUTF8(encoded_original_query), *i, &url); | 929 "oq", base::UTF16ToUTF8(encoded_original_query), *i, &url); |
| 929 } | 930 } |
| 930 break; | 931 break; |
| 931 | 932 |
| 932 case GOOGLE_PAGE_CLASSIFICATION: | 933 case GOOGLE_PAGE_CLASSIFICATION: |
| 933 if (search_terms_args.page_classification != | 934 if (search_terms_args.page_classification != |
| 934 AutocompleteInput::INVALID_SPEC) { | 935 AutocompleteInput::INVALID_SPEC) { |
| 935 HandleReplacement( | 936 HandleReplacement( |
| 936 "pgcl", base::IntToString(search_terms_args.page_classification), | 937 "pgcl", base::IntToString(search_terms_args.page_classification), |
| 937 *i, &url); | 938 *i, &url); |
| 938 } | 939 } |
| 939 break; | 940 break; |
| 940 | 941 |
| 941 case GOOGLE_RLZ: { | 942 case GOOGLE_RLZ: { |
| 942 DCHECK(!i->is_post_param); | 943 DCHECK(!i->is_post_param); |
| 943 // On platforms that don't have RLZ, we still want this branch | 944 // On platforms that don't have RLZ, we still want this branch |
| 944 // to happen so that we replace the RLZ template with the | 945 // to happen so that we replace the RLZ template with the |
| 945 // empty string. (If we don't handle this case, we hit a | 946 // empty string. (If we don't handle this case, we hit a |
| 946 // NOTREACHED below.) | 947 // NOTREACHED below.) |
| 947 base::string16 rlz_string = search_terms_data.GetRlzParameterValue(); | 948 base::string16 rlz_string = search_terms_data.GetRlzParameterValue(); |
| 948 if (!rlz_string.empty()) { | 949 if (!rlz_string.empty()) { |
| 949 HandleReplacement("rlz", UTF16ToUTF8(rlz_string), *i, &url); | 950 HandleReplacement("rlz", base::UTF16ToUTF8(rlz_string), *i, &url); |
| 950 } | 951 } |
| 951 break; | 952 break; |
| 952 } | 953 } |
| 953 | 954 |
| 954 case GOOGLE_SEARCH_CLIENT: { | 955 case GOOGLE_SEARCH_CLIENT: { |
| 955 DCHECK(!i->is_post_param); | 956 DCHECK(!i->is_post_param); |
| 956 std::string client = search_terms_data.GetSearchClient(); | 957 std::string client = search_terms_data.GetSearchClient(); |
| 957 if (!client.empty()) | 958 if (!client.empty()) |
| 958 HandleReplacement("client", client, *i, &url); | 959 HandleReplacement("client", client, *i, &url); |
| 959 break; | 960 break; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 985 HandleReplacement(std::string(), unescaped_terms, *i, &url); | 986 HandleReplacement(std::string(), unescaped_terms, *i, &url); |
| 986 break; | 987 break; |
| 987 } | 988 } |
| 988 | 989 |
| 989 case LANGUAGE: | 990 case LANGUAGE: |
| 990 HandleReplacement( | 991 HandleReplacement( |
| 991 std::string(), search_terms_data.GetApplicationLocale(), *i, &url); | 992 std::string(), search_terms_data.GetApplicationLocale(), *i, &url); |
| 992 break; | 993 break; |
| 993 | 994 |
| 994 case SEARCH_TERMS: | 995 case SEARCH_TERMS: |
| 995 HandleReplacement(std::string(), UTF16ToUTF8(encoded_terms), *i, &url); | 996 HandleReplacement( |
| 997 std::string(), base::UTF16ToUTF8(encoded_terms), *i, &url); |
| 996 break; | 998 break; |
| 997 | 999 |
| 998 case GOOGLE_IMAGE_THUMBNAIL: | 1000 case GOOGLE_IMAGE_THUMBNAIL: |
| 999 HandleReplacement( | 1001 HandleReplacement( |
| 1000 std::string(), search_terms_args.image_thumbnail_content, *i, &url); | 1002 std::string(), search_terms_args.image_thumbnail_content, *i, &url); |
| 1001 break; | 1003 break; |
| 1002 | 1004 |
| 1003 case GOOGLE_IMAGE_URL: | 1005 case GOOGLE_IMAGE_URL: |
| 1004 if (search_terms_args.image_url.is_valid()) { | 1006 if (search_terms_args.image_url.is_valid()) { |
| 1005 HandleReplacement( | 1007 HandleReplacement( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1043 TemplateURLData::TemplateURLData() | 1045 TemplateURLData::TemplateURLData() |
| 1044 : show_in_default_list(false), | 1046 : show_in_default_list(false), |
| 1045 safe_for_autoreplace(false), | 1047 safe_for_autoreplace(false), |
| 1046 id(0), | 1048 id(0), |
| 1047 date_created(base::Time::Now()), | 1049 date_created(base::Time::Now()), |
| 1048 last_modified(base::Time::Now()), | 1050 last_modified(base::Time::Now()), |
| 1049 created_by_policy(false), | 1051 created_by_policy(false), |
| 1050 usage_count(0), | 1052 usage_count(0), |
| 1051 prepopulate_id(0), | 1053 prepopulate_id(0), |
| 1052 sync_guid(base::GenerateGUID()), | 1054 sync_guid(base::GenerateGUID()), |
| 1053 keyword_(ASCIIToUTF16("dummy")), | 1055 keyword_(base::ASCIIToUTF16("dummy")), |
| 1054 url_("x") { | 1056 url_("x") { |
| 1055 } | 1057 } |
| 1056 | 1058 |
| 1057 TemplateURLData::~TemplateURLData() { | 1059 TemplateURLData::~TemplateURLData() { |
| 1058 } | 1060 } |
| 1059 | 1061 |
| 1060 void TemplateURLData::SetKeyword(const base::string16& keyword) { | 1062 void TemplateURLData::SetKeyword(const base::string16& keyword) { |
| 1061 DCHECK(!keyword.empty()); | 1063 DCHECK(!keyword.empty()); |
| 1062 | 1064 |
| 1063 // Case sensitive keyword matching is confusing. As such, we force all | 1065 // Case sensitive keyword matching is confusing. As such, we force all |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1125 return SupportsReplacementUsingTermsData(search_terms_data); | 1127 return SupportsReplacementUsingTermsData(search_terms_data); |
| 1126 } | 1128 } |
| 1127 | 1129 |
| 1128 bool TemplateURL::SupportsReplacementUsingTermsData( | 1130 bool TemplateURL::SupportsReplacementUsingTermsData( |
| 1129 const SearchTermsData& search_terms_data) const { | 1131 const SearchTermsData& search_terms_data) const { |
| 1130 return url_ref_.SupportsReplacementUsingTermsData(search_terms_data); | 1132 return url_ref_.SupportsReplacementUsingTermsData(search_terms_data); |
| 1131 } | 1133 } |
| 1132 | 1134 |
| 1133 bool TemplateURL::IsGoogleSearchURLWithReplaceableKeyword() const { | 1135 bool TemplateURL::IsGoogleSearchURLWithReplaceableKeyword() const { |
| 1134 return (GetType() == NORMAL) && url_ref_.HasGoogleBaseURLs() && | 1136 return (GetType() == NORMAL) && url_ref_.HasGoogleBaseURLs() && |
| 1135 google_util::IsGoogleHostname(UTF16ToUTF8(data_.keyword()), | 1137 google_util::IsGoogleHostname(base::UTF16ToUTF8(data_.keyword()), |
| 1136 google_util::DISALLOW_SUBDOMAIN); | 1138 google_util::DISALLOW_SUBDOMAIN); |
| 1137 } | 1139 } |
| 1138 | 1140 |
| 1139 bool TemplateURL::HasSameKeywordAs(const TemplateURL& other) const { | 1141 bool TemplateURL::HasSameKeywordAs(const TemplateURL& other) const { |
| 1140 return (data_.keyword() == other.data_.keyword()) || | 1142 return (data_.keyword() == other.data_.keyword()) || |
| 1141 (IsGoogleSearchURLWithReplaceableKeyword() && | 1143 (IsGoogleSearchURLWithReplaceableKeyword() && |
| 1142 other.IsGoogleSearchURLWithReplaceableKeyword()); | 1144 other.IsGoogleSearchURLWithReplaceableKeyword()); |
| 1143 } | 1145 } |
| 1144 | 1146 |
| 1145 TemplateURL::Type TemplateURL::GetType() const { | 1147 TemplateURL::Type TemplateURL::GetType() const { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1235 // and ref are encoded in the same way. | 1237 // and ref are encoded in the same way. |
| 1236 std::string input_encoding; | 1238 std::string input_encoding; |
| 1237 base::string16 encoded_terms; | 1239 base::string16 encoded_terms; |
| 1238 base::string16 encoded_original_query; | 1240 base::string16 encoded_original_query; |
| 1239 EncodeSearchTerms(search_terms_args, true, &input_encoding, | 1241 EncodeSearchTerms(search_terms_args, true, &input_encoding, |
| 1240 &encoded_terms, &encoded_original_query); | 1242 &encoded_terms, &encoded_original_query); |
| 1241 | 1243 |
| 1242 std::string old_params((search_term_component == url_parse::Parsed::REF) ? | 1244 std::string old_params((search_term_component == url_parse::Parsed::REF) ? |
| 1243 url.ref() : url.query()); | 1245 url.ref() : url.query()); |
| 1244 std::string new_params(old_params, 0, search_terms_position.begin); | 1246 std::string new_params(old_params, 0, search_terms_position.begin); |
| 1245 new_params += UTF16ToUTF8(search_terms_args.search_terms); | 1247 new_params += base::UTF16ToUTF8(search_terms_args.search_terms); |
| 1246 new_params += old_params.substr(search_terms_position.end()); | 1248 new_params += old_params.substr(search_terms_position.end()); |
| 1247 url_canon::StdStringReplacements<std::string> replacements; | 1249 url_canon::StdStringReplacements<std::string> replacements; |
| 1248 if (search_term_component == url_parse::Parsed::REF) | 1250 if (search_term_component == url_parse::Parsed::REF) |
| 1249 replacements.SetRefStr(new_params); | 1251 replacements.SetRefStr(new_params); |
| 1250 else | 1252 else |
| 1251 replacements.SetQueryStr(new_params); | 1253 replacements.SetQueryStr(new_params); |
| 1252 *result = url.ReplaceComponents(replacements); | 1254 *result = url.ReplaceComponents(replacements); |
| 1253 return true; | 1255 return true; |
| 1254 } | 1256 } |
| 1255 | 1257 |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 // patterns. This means that given patterns | 1331 // patterns. This means that given patterns |
| 1330 // [ "http://foo/#q={searchTerms}", "http://foo/?q={searchTerms}" ], | 1332 // [ "http://foo/#q={searchTerms}", "http://foo/?q={searchTerms}" ], |
| 1331 // calling ExtractSearchTermsFromURL() on "http://foo/?q=bar#q=' would | 1333 // calling ExtractSearchTermsFromURL() on "http://foo/?q=bar#q=' would |
| 1332 // return false. This is important for at least Google, where such URLs | 1334 // return false. This is important for at least Google, where such URLs |
| 1333 // are invalid. | 1335 // are invalid. |
| 1334 return !search_terms->empty(); | 1336 return !search_terms->empty(); |
| 1335 } | 1337 } |
| 1336 } | 1338 } |
| 1337 return false; | 1339 return false; |
| 1338 } | 1340 } |
| OLD | NEW |