Chromium Code Reviews| 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 "base/guid.h" | 7 #include "base/guid.h" |
| 8 #include "base/i18n/case_conversion.h" | 8 #include "base/i18n/case_conversion.h" |
| 9 #include "base/i18n/icu_string_conversions.h" | 9 #include "base/i18n/icu_string_conversions.h" |
| 10 #include "base/i18n/rtl.h" | 10 #include "base/i18n/rtl.h" |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 35 const char kSearchTermsParameter[] = "searchTerms"; | 35 const char kSearchTermsParameter[] = "searchTerms"; |
| 36 const char kSearchTermsParameterFull[] = "{searchTerms}"; | 36 const char kSearchTermsParameterFull[] = "{searchTerms}"; |
| 37 const char kCountParameter[] = "count"; | 37 const char kCountParameter[] = "count"; |
| 38 const char kStartIndexParameter[] = "startIndex"; | 38 const char kStartIndexParameter[] = "startIndex"; |
| 39 const char kStartPageParameter[] = "startPage"; | 39 const char kStartPageParameter[] = "startPage"; |
| 40 const char kLanguageParameter[] = "language"; | 40 const char kLanguageParameter[] = "language"; |
| 41 const char kInputEncodingParameter[] = "inputEncoding"; | 41 const char kInputEncodingParameter[] = "inputEncoding"; |
| 42 const char kOutputEncodingParameter[] = "outputEncoding"; | 42 const char kOutputEncodingParameter[] = "outputEncoding"; |
| 43 | 43 |
| 44 const char kGoogleAcceptedSuggestionParameter[] = "google:acceptedSuggestion"; | 44 const char kGoogleAcceptedSuggestionParameter[] = "google:acceptedSuggestion"; |
| 45 const char kGoogleAssistedQueryStatsParameter[] = "google:assistedQueryStats"; | |
| 45 // Host/Domain Google searches are relative to. | 46 // Host/Domain Google searches are relative to. |
| 46 const char kGoogleBaseURLParameter[] = "google:baseURL"; | 47 const char kGoogleBaseURLParameter[] = "google:baseURL"; |
| 47 const char kGoogleBaseURLParameterFull[] = "{google:baseURL}"; | 48 const char kGoogleBaseURLParameterFull[] = "{google:baseURL}"; |
| 48 // Like google:baseURL, but for the Search Suggest capability. | 49 // Like google:baseURL, but for the Search Suggest capability. |
| 49 const char kGoogleBaseSuggestURLParameter[] = "google:baseSuggestURL"; | 50 const char kGoogleBaseSuggestURLParameter[] = "google:baseSuggestURL"; |
| 50 const char kGoogleBaseSuggestURLParameterFull[] = "{google:baseSuggestURL}"; | 51 const char kGoogleBaseSuggestURLParameterFull[] = "{google:baseSuggestURL}"; |
| 51 const char kGoogleInstantEnabledParameter[] = "google:instantEnabledParameter"; | 52 const char kGoogleInstantEnabledParameter[] = "google:instantEnabledParameter"; |
| 52 const char kGoogleOriginalQueryForSuggestionParameter[] = | 53 const char kGoogleOriginalQueryForSuggestionParameter[] = |
| 53 "google:originalQueryForSuggestion"; | 54 "google:originalQueryForSuggestion"; |
| 54 const char kGoogleRLZParameter[] = "google:RLZ"; | 55 const char kGoogleRLZParameter[] = "google:RLZ"; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 base::OnStringConversionError::SKIP, &encoded_original_query)) | 100 base::OnStringConversionError::SKIP, &encoded_original_query)) |
| 100 return false; | 101 return false; |
| 101 *escaped_original_query = | 102 *escaped_original_query = |
| 102 UTF8ToUTF16(net::EscapeQueryParamValue(encoded_original_query, true)); | 103 UTF8ToUTF16(net::EscapeQueryParamValue(encoded_original_query, true)); |
| 103 return true; | 104 return true; |
| 104 } | 105 } |
| 105 | 106 |
| 106 } // namespace | 107 } // namespace |
| 107 | 108 |
| 108 | 109 |
| 109 // TemplateURLRef ------------------------------------------------------------- | 110 // TemplateURLRef ------------------------------------------------------------- |
|
Peter Kasting
2012/06/18 19:45:52
Nit: Move this below and put a "// TemplateURLRef:
Bart N
2012/06/18 20:34:18
Done.
| |
| 110 | 111 |
| 112 TemplateURLRef::SearchTermsArgs::SearchTermsArgs(const string16& search_terms) | |
| 113 : search_terms(search_terms), | |
| 114 accepted_suggestion(NO_SUGGESTIONS_AVAILABLE) { | |
| 115 } | |
| 116 | |
| 111 TemplateURLRef::TemplateURLRef(TemplateURL* owner, Type type) | 117 TemplateURLRef::TemplateURLRef(TemplateURL* owner, Type type) |
| 112 : owner_(owner), | 118 : owner_(owner), |
| 113 type_(type), | 119 type_(type), |
| 114 parsed_(false), | 120 parsed_(false), |
| 115 valid_(false), | 121 valid_(false), |
| 116 supports_replacements_(false), | 122 supports_replacements_(false), |
| 117 prepopulated_(false) { | 123 prepopulated_(false) { |
| 118 DCHECK(owner_); | 124 DCHECK(owner_); |
| 119 } | 125 } |
| 120 | 126 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 135 return SupportsReplacementUsingTermsData(search_terms_data); | 141 return SupportsReplacementUsingTermsData(search_terms_data); |
| 136 } | 142 } |
| 137 | 143 |
| 138 bool TemplateURLRef::SupportsReplacementUsingTermsData( | 144 bool TemplateURLRef::SupportsReplacementUsingTermsData( |
| 139 const SearchTermsData& search_terms_data) const { | 145 const SearchTermsData& search_terms_data) const { |
| 140 ParseIfNecessaryUsingTermsData(search_terms_data); | 146 ParseIfNecessaryUsingTermsData(search_terms_data); |
| 141 return valid_ && supports_replacements_; | 147 return valid_ && supports_replacements_; |
| 142 } | 148 } |
| 143 | 149 |
| 144 std::string TemplateURLRef::ReplaceSearchTerms( | 150 std::string TemplateURLRef::ReplaceSearchTerms( |
| 145 const string16& terms, | 151 const SearchTermsArgs& search_terms_args) const { |
| 146 int accepted_suggestion, | 152 return ReplaceSearchTermsUsingTermsData( |
| 147 const string16& original_query_for_suggestion) const { | 153 search_terms_args, UIThreadSearchTermsData(owner_->profile())); |
| 148 UIThreadSearchTermsData search_terms_data(owner_->profile()); | |
| 149 return ReplaceSearchTermsUsingTermsData(terms, accepted_suggestion, | |
| 150 original_query_for_suggestion, search_terms_data); | |
| 151 } | 154 } |
| 152 | 155 |
| 153 std::string TemplateURLRef::ReplaceSearchTermsUsingTermsData( | 156 std::string TemplateURLRef::ReplaceSearchTermsUsingTermsData( |
| 154 const string16& terms, | 157 const SearchTermsArgs& search_terms_args, |
| 155 int accepted_suggestion, | |
| 156 const string16& original_query_for_suggestion, | |
| 157 const SearchTermsData& search_terms_data) const { | 158 const SearchTermsData& search_terms_data) const { |
| 158 ParseIfNecessaryUsingTermsData(search_terms_data); | 159 ParseIfNecessaryUsingTermsData(search_terms_data); |
| 159 if (!valid_) | 160 if (!valid_) |
| 160 return std::string(); | 161 return std::string(); |
| 161 | 162 |
| 162 if (replacements_.empty()) | 163 if (replacements_.empty()) |
| 163 return parsed_url_; | 164 return parsed_url_; |
| 164 | 165 |
| 165 // Determine if the search terms are in the query or before. We're escaping | 166 // Determine if the search terms are in the query or before. We're escaping |
| 166 // space as '+' in the former case and as '%20' in the latter case. | 167 // space as '+' in the former case and as '%20' in the latter case. |
| 167 bool is_in_query = true; | 168 bool is_in_query = true; |
| 168 for (Replacements::iterator i = replacements_.begin(); | 169 for (Replacements::iterator i = replacements_.begin(); |
| 169 i != replacements_.end(); ++i) { | 170 i != replacements_.end(); ++i) { |
| 170 if (i->type == SEARCH_TERMS) { | 171 if (i->type == SEARCH_TERMS) { |
| 171 string16::size_type query_start = parsed_url_.find('?'); | 172 string16::size_type query_start = parsed_url_.find('?'); |
| 172 is_in_query = query_start != string16::npos && | 173 is_in_query = query_start != string16::npos && |
| 173 (static_cast<string16::size_type>(i->index) > query_start); | 174 (static_cast<string16::size_type>(i->index) > query_start); |
| 174 break; | 175 break; |
| 175 } | 176 } |
| 176 } | 177 } |
| 177 | 178 |
| 178 string16 encoded_terms; | 179 string16 encoded_terms; |
| 179 string16 encoded_original_query; | 180 string16 encoded_original_query; |
| 180 std::string input_encoding; | 181 std::string input_encoding; |
| 181 // Encode the search terms so that we know the encoding. | 182 // Encode the search terms so that we know the encoding. |
| 182 for (std::vector<std::string>::const_iterator i( | 183 for (std::vector<std::string>::const_iterator i( |
| 183 owner_->input_encodings().begin()); | 184 owner_->input_encodings().begin()); |
| 184 i != owner_->input_encodings().end(); ++i) { | 185 i != owner_->input_encodings().end(); ++i) { |
| 185 if (TryEncoding(terms, original_query_for_suggestion, i->c_str(), | 186 if (TryEncoding(search_terms_args.search_terms, |
| 187 search_terms_args.original_query, i->c_str(), | |
| 186 is_in_query, &encoded_terms, &encoded_original_query)) { | 188 is_in_query, &encoded_terms, &encoded_original_query)) { |
| 187 input_encoding = *i; | 189 input_encoding = *i; |
| 188 break; | 190 break; |
| 189 } | 191 } |
| 190 } | 192 } |
| 191 if (input_encoding.empty()) { | 193 if (input_encoding.empty()) { |
| 192 input_encoding = "UTF-8"; | 194 input_encoding = "UTF-8"; |
| 193 if (!TryEncoding(terms, original_query_for_suggestion, | 195 if (!TryEncoding(search_terms_args.search_terms, |
| 196 search_terms_args.original_query, | |
| 194 input_encoding.c_str(), is_in_query, &encoded_terms, | 197 input_encoding.c_str(), is_in_query, &encoded_terms, |
| 195 &encoded_original_query)) | 198 &encoded_original_query)) |
| 196 NOTREACHED(); | 199 NOTREACHED(); |
| 197 } | 200 } |
| 198 | 201 |
| 199 std::string url = parsed_url_; | 202 std::string url = parsed_url_; |
| 200 | 203 |
| 201 // replacements_ is ordered in ascending order, as such we need to iterate | 204 // replacements_ is ordered in ascending order, as such we need to iterate |
| 202 // from the back. | 205 // from the back. |
| 203 for (Replacements::reverse_iterator i = replacements_.rbegin(); | 206 for (Replacements::reverse_iterator i = replacements_.rbegin(); |
| 204 i != replacements_.rend(); ++i) { | 207 i != replacements_.rend(); ++i) { |
| 205 switch (i->type) { | 208 switch (i->type) { |
| 206 case ENCODING: | 209 case ENCODING: |
| 207 url.insert(i->index, input_encoding); | 210 url.insert(i->index, input_encoding); |
| 208 break; | 211 break; |
| 209 | 212 |
| 213 case GOOGLE_ASSISTED_QUERY_STATS: | |
| 214 if (!search_terms_args.assisted_query_stats.empty()) { | |
| 215 url.insert(i->index, "aqs=" + search_terms_args.assisted_query_stats + | |
| 216 "&"); | |
| 217 } | |
| 218 break; | |
| 219 | |
| 210 case GOOGLE_ACCEPTED_SUGGESTION: | 220 case GOOGLE_ACCEPTED_SUGGESTION: |
| 211 if (accepted_suggestion == NO_SUGGESTION_CHOSEN) | 221 if (search_terms_args.accepted_suggestion == NO_SUGGESTION_CHOSEN) { |
| 212 url.insert(i->index, "aq=f&"); | 222 url.insert(i->index, "aq=f&"); |
| 213 else if (accepted_suggestion != NO_SUGGESTIONS_AVAILABLE) | 223 } else if (search_terms_args.accepted_suggestion != |
| 224 NO_SUGGESTIONS_AVAILABLE) { | |
| 214 url.insert(i->index, | 225 url.insert(i->index, |
| 215 base::StringPrintf("aq=%d&", accepted_suggestion)); | 226 base::StringPrintf("aq=%d&", |
| 227 search_terms_args.accepted_suggestion)); | |
| 228 } | |
| 216 break; | 229 break; |
| 217 | 230 |
| 218 case GOOGLE_BASE_URL: | 231 case GOOGLE_BASE_URL: |
| 219 url.insert(i->index, search_terms_data.GoogleBaseURLValue()); | 232 url.insert(i->index, search_terms_data.GoogleBaseURLValue()); |
| 220 break; | 233 break; |
| 221 | 234 |
| 222 case GOOGLE_BASE_SUGGEST_URL: | 235 case GOOGLE_BASE_SUGGEST_URL: |
| 223 url.insert(i->index, search_terms_data.GoogleBaseSuggestURLValue()); | 236 url.insert(i->index, search_terms_data.GoogleBaseSuggestURLValue()); |
| 224 break; | 237 break; |
| 225 | 238 |
| 226 case GOOGLE_INSTANT_ENABLED: | 239 case GOOGLE_INSTANT_ENABLED: |
| 227 url.insert(i->index, search_terms_data.InstantEnabledParam()); | 240 url.insert(i->index, search_terms_data.InstantEnabledParam()); |
| 228 break; | 241 break; |
| 229 | 242 |
| 230 case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION: | 243 case GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION: |
| 231 if (accepted_suggestion >= 0) | 244 if (search_terms_args.accepted_suggestion >= 0 || |
| 245 !search_terms_args.assisted_query_stats.empty()) { | |
| 232 url.insert(i->index, "oq=" + UTF16ToUTF8(encoded_original_query) + | 246 url.insert(i->index, "oq=" + UTF16ToUTF8(encoded_original_query) + |
| 233 "&"); | 247 "&"); |
| 248 } | |
| 234 break; | 249 break; |
| 235 | 250 |
| 236 case GOOGLE_RLZ: { | 251 case GOOGLE_RLZ: { |
| 237 // On platforms that don't have RLZ, we still want this branch | 252 // On platforms that don't have RLZ, we still want this branch |
| 238 // to happen so that we replace the RLZ template with the | 253 // to happen so that we replace the RLZ template with the |
| 239 // empty string. (If we don't handle this case, we hit a | 254 // empty string. (If we don't handle this case, we hit a |
| 240 // NOTREACHED below.) | 255 // NOTREACHED below.) |
| 241 #if defined(ENABLE_RLZ) | 256 #if defined(ENABLE_RLZ) |
| 242 string16 rlz_string = search_terms_data.GetRlzParameterValue(); | 257 string16 rlz_string = search_terms_data.GetRlzParameterValue(); |
| 243 if (!rlz_string.empty()) { | 258 if (!rlz_string.empty()) { |
| 244 url.insert(i->index, "rlz=" + UTF16ToUTF8(rlz_string) + "&"); | 259 url.insert(i->index, "rlz=" + UTF16ToUTF8(rlz_string) + "&"); |
| 245 } | 260 } |
| 246 #endif | 261 #endif |
| 247 break; | 262 break; |
| 248 } | 263 } |
| 249 | 264 |
| 250 case GOOGLE_SEARCH_FIELDTRIAL_GROUP: | 265 case GOOGLE_SEARCH_FIELDTRIAL_GROUP: |
| 251 if (AutocompleteFieldTrial::InSuggestFieldTrial()) { | 266 if (AutocompleteFieldTrial::InSuggestFieldTrial()) { |
| 252 // Add something like sugexp=chrome,mod=5 to the URL request. | 267 // Add something like sugexp=chrome,mod=5 to the URL request. |
| 253 url.insert(i->index, "sugexp=chrome,mod=" + | 268 url.insert(i->index, "sugexp=chrome,mod=" + |
| 254 AutocompleteFieldTrial::GetSuggestGroupName() + "&"); | 269 AutocompleteFieldTrial::GetSuggestGroupName() + "&"); |
| 255 } | 270 } |
| 256 break; | 271 break; |
| 257 | 272 |
| 258 case GOOGLE_UNESCAPED_SEARCH_TERMS: { | 273 case GOOGLE_UNESCAPED_SEARCH_TERMS: { |
| 259 std::string unescaped_terms; | 274 std::string unescaped_terms; |
| 260 base::UTF16ToCodepage(terms, input_encoding.c_str(), | 275 base::UTF16ToCodepage(search_terms_args.search_terms, |
| 276 input_encoding.c_str(), | |
| 261 base::OnStringConversionError::SKIP, | 277 base::OnStringConversionError::SKIP, |
| 262 &unescaped_terms); | 278 &unescaped_terms); |
| 263 url.insert(i->index, std::string(unescaped_terms.begin(), | 279 url.insert(i->index, std::string(unescaped_terms.begin(), |
| 264 unescaped_terms.end())); | 280 unescaped_terms.end())); |
| 265 break; | 281 break; |
| 266 } | 282 } |
| 267 | 283 |
| 268 case LANGUAGE: | 284 case LANGUAGE: |
| 269 url.insert(i->index, search_terms_data.GetApplicationLocale()); | 285 url.insert(i->index, search_terms_data.GetApplicationLocale()); |
| 270 break; | 286 break; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 410 url->insert(start, "1"); | 426 url->insert(start, "1"); |
| 411 } else if (parameter == kLanguageParameter) { | 427 } else if (parameter == kLanguageParameter) { |
| 412 replacements->push_back(Replacement(LANGUAGE, start)); | 428 replacements->push_back(Replacement(LANGUAGE, start)); |
| 413 } else if (parameter == kInputEncodingParameter) { | 429 } else if (parameter == kInputEncodingParameter) { |
| 414 replacements->push_back(Replacement(ENCODING, start)); | 430 replacements->push_back(Replacement(ENCODING, start)); |
| 415 } else if (parameter == kOutputEncodingParameter) { | 431 } else if (parameter == kOutputEncodingParameter) { |
| 416 if (!optional) | 432 if (!optional) |
| 417 url->insert(start, kOutputEncodingType); | 433 url->insert(start, kOutputEncodingType); |
| 418 } else if (parameter == kGoogleAcceptedSuggestionParameter) { | 434 } else if (parameter == kGoogleAcceptedSuggestionParameter) { |
| 419 replacements->push_back(Replacement(GOOGLE_ACCEPTED_SUGGESTION, start)); | 435 replacements->push_back(Replacement(GOOGLE_ACCEPTED_SUGGESTION, start)); |
| 436 } else if (parameter == kGoogleAssistedQueryStatsParameter) { | |
| 437 replacements->push_back(Replacement(GOOGLE_ASSISTED_QUERY_STATS, start)); | |
| 420 } else if (parameter == kGoogleBaseURLParameter) { | 438 } else if (parameter == kGoogleBaseURLParameter) { |
| 421 replacements->push_back(Replacement(GOOGLE_BASE_URL, start)); | 439 replacements->push_back(Replacement(GOOGLE_BASE_URL, start)); |
| 422 } else if (parameter == kGoogleBaseSuggestURLParameter) { | 440 } else if (parameter == kGoogleBaseSuggestURLParameter) { |
| 423 replacements->push_back(Replacement(GOOGLE_BASE_SUGGEST_URL, start)); | 441 replacements->push_back(Replacement(GOOGLE_BASE_SUGGEST_URL, start)); |
| 424 } else if (parameter == kGoogleInstantEnabledParameter) { | 442 } else if (parameter == kGoogleInstantEnabledParameter) { |
| 425 replacements->push_back(Replacement(GOOGLE_INSTANT_ENABLED, start)); | 443 replacements->push_back(Replacement(GOOGLE_INSTANT_ENABLED, start)); |
| 426 } else if (parameter == kGoogleOriginalQueryForSuggestionParameter) { | 444 } else if (parameter == kGoogleOriginalQueryForSuggestionParameter) { |
| 427 replacements->push_back(Replacement(GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION, | 445 replacements->push_back(Replacement(GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION, |
| 428 start)); | 446 start)); |
| 429 } else if (parameter == kGoogleRLZParameter) { | 447 } else if (parameter == kGoogleRLZParameter) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 679 } | 697 } |
| 680 | 698 |
| 681 void TemplateURL::ResetKeywordIfNecessary(bool force) { | 699 void TemplateURL::ResetKeywordIfNecessary(bool force) { |
| 682 if (IsGoogleSearchURLWithReplaceableKeyword() || force) { | 700 if (IsGoogleSearchURLWithReplaceableKeyword() || force) { |
| 683 DCHECK(!IsExtensionKeyword()); | 701 DCHECK(!IsExtensionKeyword()); |
| 684 GURL url(TemplateURLService::GenerateSearchURL(this)); | 702 GURL url(TemplateURLService::GenerateSearchURL(this)); |
| 685 if (url.is_valid()) | 703 if (url.is_valid()) |
| 686 data_.SetKeyword(TemplateURLService::GenerateKeyword(url)); | 704 data_.SetKeyword(TemplateURLService::GenerateKeyword(url)); |
| 687 } | 705 } |
| 688 } | 706 } |
| OLD | NEW |