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/autocomplete/autocomplete_match.h" | 5 #include "chrome/browser/autocomplete/autocomplete_match.h" |
6 | 6 |
7 #include "base/i18n/time_formatting.h" | 7 #include "base/i18n/time_formatting.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/strings/string16.h" | 9 #include "base/strings/string16.h" |
10 #include "base/strings/string_number_conversions.h" | 10 #include "base/strings/string_number_conversions.h" |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 bool AutocompleteMatch::DestinationsEqual(const AutocompleteMatch& elem1, | 189 bool AutocompleteMatch::DestinationsEqual(const AutocompleteMatch& elem1, |
190 const AutocompleteMatch& elem2) { | 190 const AutocompleteMatch& elem2) { |
191 if (elem1.stripped_destination_url.is_empty() && | 191 if (elem1.stripped_destination_url.is_empty() && |
192 elem2.stripped_destination_url.is_empty()) | 192 elem2.stripped_destination_url.is_empty()) |
193 return false; | 193 return false; |
194 return elem1.stripped_destination_url == elem2.stripped_destination_url; | 194 return elem1.stripped_destination_url == elem2.stripped_destination_url; |
195 } | 195 } |
196 | 196 |
197 // static | 197 // static |
198 void AutocompleteMatch::ClassifyMatchInString( | 198 void AutocompleteMatch::ClassifyMatchInString( |
199 const string16& find_text, | 199 const base::string16& find_text, |
200 const string16& text, | 200 const base::string16& text, |
201 int style, | 201 int style, |
202 ACMatchClassifications* classification) { | 202 ACMatchClassifications* classification) { |
203 ClassifyLocationInString(text.find(find_text), find_text.length(), | 203 ClassifyLocationInString(text.find(find_text), find_text.length(), |
204 text.length(), style, classification); | 204 text.length(), style, classification); |
205 } | 205 } |
206 | 206 |
207 // static | 207 // static |
208 void AutocompleteMatch::ClassifyLocationInString( | 208 void AutocompleteMatch::ClassifyLocationInString( |
209 size_t match_location, | 209 size_t match_location, |
210 size_t match_length, | 210 size_t match_length, |
211 size_t overall_length, | 211 size_t overall_length, |
212 int style, | 212 int style, |
213 ACMatchClassifications* classification) { | 213 ACMatchClassifications* classification) { |
214 classification->clear(); | 214 classification->clear(); |
215 | 215 |
216 // Don't classify anything about an empty string | 216 // Don't classify anything about an empty string |
217 // (AutocompleteMatch::Validate() checks this). | 217 // (AutocompleteMatch::Validate() checks this). |
218 if (overall_length == 0) | 218 if (overall_length == 0) |
219 return; | 219 return; |
220 | 220 |
221 // Mark pre-match portion of string (if any). | 221 // Mark pre-match portion of string (if any). |
222 if (match_location != 0) { | 222 if (match_location != 0) { |
223 classification->push_back(ACMatchClassification(0, style)); | 223 classification->push_back(ACMatchClassification(0, style)); |
224 } | 224 } |
225 | 225 |
226 // Mark matching portion of string. | 226 // Mark matching portion of string. |
227 if (match_location == string16::npos) { | 227 if (match_location == base::string16::npos) { |
228 // No match, above classification will suffice for whole string. | 228 // No match, above classification will suffice for whole string. |
229 return; | 229 return; |
230 } | 230 } |
231 // Classifying an empty match makes no sense and will lead to validation | 231 // Classifying an empty match makes no sense and will lead to validation |
232 // errors later. | 232 // errors later. |
233 DCHECK_GT(match_length, 0U); | 233 DCHECK_GT(match_length, 0U); |
234 classification->push_back(ACMatchClassification(match_location, | 234 classification->push_back(ACMatchClassification(match_location, |
235 (style | ACMatchClassification::MATCH) & ~ACMatchClassification::DIM)); | 235 (style | ACMatchClassification::MATCH) & ~ACMatchClassification::DIM)); |
236 | 236 |
237 // Mark post-match portion of string (if any). | 237 // Mark post-match portion of string (if any). |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 int style) { | 313 int style) { |
314 DCHECK(classifications); | 314 DCHECK(classifications); |
315 if (classifications->empty() || classifications->back().style != style) { | 315 if (classifications->empty() || classifications->back().style != style) { |
316 DCHECK(classifications->empty() || | 316 DCHECK(classifications->empty() || |
317 (offset > classifications->back().offset)); | 317 (offset > classifications->back().offset)); |
318 classifications->push_back(ACMatchClassification(offset, style)); | 318 classifications->push_back(ACMatchClassification(offset, style)); |
319 } | 319 } |
320 } | 320 } |
321 | 321 |
322 // static | 322 // static |
323 string16 AutocompleteMatch::SanitizeString(const string16& text) { | 323 base::string16 AutocompleteMatch::SanitizeString(const base::string16& text) { |
324 // NOTE: This logic is mirrored by |sanitizeString()| in | 324 // NOTE: This logic is mirrored by |sanitizeString()| in |
325 // omnibox_custom_bindings.js. | 325 // omnibox_custom_bindings.js. |
326 string16 result; | 326 base::string16 result; |
327 TrimWhitespace(text, TRIM_LEADING, &result); | 327 TrimWhitespace(text, TRIM_LEADING, &result); |
328 base::RemoveChars(result, kInvalidChars, &result); | 328 base::RemoveChars(result, kInvalidChars, &result); |
329 return result; | 329 return result; |
330 } | 330 } |
331 | 331 |
332 // static | 332 // static |
333 bool AutocompleteMatch::IsSearchType(Type type) { | 333 bool AutocompleteMatch::IsSearchType(Type type) { |
334 return type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || | 334 return type == AutocompleteMatchType::SEARCH_WHAT_YOU_TYPED || |
335 type == AutocompleteMatchType::SEARCH_HISTORY || | 335 type == AutocompleteMatchType::SEARCH_HISTORY || |
336 type == AutocompleteMatchType::SEARCH_SUGGEST || | 336 type == AutocompleteMatchType::SEARCH_SUGGEST || |
337 type == AutocompleteMatchType::SEARCH_OTHER_ENGINE; | 337 type == AutocompleteMatchType::SEARCH_OTHER_ENGINE; |
338 } | 338 } |
339 | 339 |
340 void AutocompleteMatch::ComputeStrippedDestinationURL(Profile* profile) { | 340 void AutocompleteMatch::ComputeStrippedDestinationURL(Profile* profile) { |
341 stripped_destination_url = destination_url; | 341 stripped_destination_url = destination_url; |
342 if (!stripped_destination_url.is_valid()) | 342 if (!stripped_destination_url.is_valid()) |
343 return; | 343 return; |
344 | 344 |
345 // If the destination URL looks like it was generated from a TemplateURL, | 345 // If the destination URL looks like it was generated from a TemplateURL, |
346 // remove all substitutions other than the search terms. This allows us | 346 // remove all substitutions other than the search terms. This allows us |
347 // to eliminate cases like past search URLs from history that differ only | 347 // to eliminate cases like past search URLs from history that differ only |
348 // by some obscure query param from each other or from the search/keyword | 348 // by some obscure query param from each other or from the search/keyword |
349 // provider matches. | 349 // provider matches. |
350 TemplateURL* template_url = GetTemplateURL(profile, true); | 350 TemplateURL* template_url = GetTemplateURL(profile, true); |
351 if (template_url != NULL && template_url->SupportsReplacement()) { | 351 if (template_url != NULL && template_url->SupportsReplacement()) { |
352 string16 search_terms; | 352 base::string16 search_terms; |
353 if (template_url->ExtractSearchTermsFromURL(stripped_destination_url, | 353 if (template_url->ExtractSearchTermsFromURL(stripped_destination_url, |
354 &search_terms)) { | 354 &search_terms)) { |
355 stripped_destination_url = | 355 stripped_destination_url = |
356 GURL(template_url->url_ref().ReplaceSearchTerms( | 356 GURL(template_url->url_ref().ReplaceSearchTerms( |
357 TemplateURLRef::SearchTermsArgs(search_terms))); | 357 TemplateURLRef::SearchTermsArgs(search_terms))); |
358 } | 358 } |
359 } | 359 } |
360 | 360 |
361 // |replacements| keeps all the substitions we're going to make to | 361 // |replacements| keeps all the substitions we're going to make to |
362 // from {destination_url} to {stripped_destination_url}. |need_replacement| | 362 // from {destination_url} to {stripped_destination_url}. |need_replacement| |
(...skipping 19 matching lines...) Expand all Loading... |
382 url_parse::Component(0, strlen(content::kHttpScheme))); | 382 url_parse::Component(0, strlen(content::kHttpScheme))); |
383 needs_replacement = true; | 383 needs_replacement = true; |
384 } | 384 } |
385 | 385 |
386 if (needs_replacement) | 386 if (needs_replacement) |
387 stripped_destination_url = stripped_destination_url.ReplaceComponents( | 387 stripped_destination_url = stripped_destination_url.ReplaceComponents( |
388 replacements); | 388 replacements); |
389 } | 389 } |
390 | 390 |
391 void AutocompleteMatch::GetKeywordUIState(Profile* profile, | 391 void AutocompleteMatch::GetKeywordUIState(Profile* profile, |
392 string16* keyword, | 392 base::string16* keyword, |
393 bool* is_keyword_hint) const { | 393 bool* is_keyword_hint) const { |
394 *is_keyword_hint = associated_keyword.get() != NULL; | 394 *is_keyword_hint = associated_keyword.get() != NULL; |
395 keyword->assign(*is_keyword_hint ? associated_keyword->keyword : | 395 keyword->assign(*is_keyword_hint ? associated_keyword->keyword : |
396 GetSubstitutingExplicitlyInvokedKeyword(profile)); | 396 GetSubstitutingExplicitlyInvokedKeyword(profile)); |
397 } | 397 } |
398 | 398 |
399 string16 AutocompleteMatch::GetSubstitutingExplicitlyInvokedKeyword( | 399 base::string16 AutocompleteMatch::GetSubstitutingExplicitlyInvokedKeyword( |
400 Profile* profile) const { | 400 Profile* profile) const { |
401 if (transition != content::PAGE_TRANSITION_KEYWORD) | 401 if (transition != content::PAGE_TRANSITION_KEYWORD) |
402 return string16(); | 402 return base::string16(); |
403 const TemplateURL* t_url = GetTemplateURL(profile, false); | 403 const TemplateURL* t_url = GetTemplateURL(profile, false); |
404 return (t_url && t_url->SupportsReplacement()) ? keyword : string16(); | 404 return (t_url && t_url->SupportsReplacement()) ? keyword : base::string16(); |
405 } | 405 } |
406 | 406 |
407 TemplateURL* AutocompleteMatch::GetTemplateURL( | 407 TemplateURL* AutocompleteMatch::GetTemplateURL( |
408 Profile* profile, bool allow_fallback_to_destination_host) const { | 408 Profile* profile, bool allow_fallback_to_destination_host) const { |
409 DCHECK(profile); | 409 DCHECK(profile); |
410 TemplateURLService* template_url_service = | 410 TemplateURLService* template_url_service = |
411 TemplateURLServiceFactory::GetForProfile(profile); | 411 TemplateURLServiceFactory::GetForProfile(profile); |
412 if (template_url_service == NULL) | 412 if (template_url_service == NULL) |
413 return NULL; | 413 return NULL; |
414 TemplateURL* template_url = keyword.empty() ? NULL : | 414 TemplateURL* template_url = keyword.empty() ? NULL : |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 is_keyword_verbatim_match; | 454 is_keyword_verbatim_match; |
455 } | 455 } |
456 | 456 |
457 #ifndef NDEBUG | 457 #ifndef NDEBUG |
458 void AutocompleteMatch::Validate() const { | 458 void AutocompleteMatch::Validate() const { |
459 ValidateClassifications(contents, contents_class); | 459 ValidateClassifications(contents, contents_class); |
460 ValidateClassifications(description, description_class); | 460 ValidateClassifications(description, description_class); |
461 } | 461 } |
462 | 462 |
463 void AutocompleteMatch::ValidateClassifications( | 463 void AutocompleteMatch::ValidateClassifications( |
464 const string16& text, | 464 const base::string16& text, |
465 const ACMatchClassifications& classifications) const { | 465 const ACMatchClassifications& classifications) const { |
466 if (text.empty()) { | 466 if (text.empty()) { |
467 DCHECK(classifications.empty()); | 467 DCHECK(classifications.empty()); |
468 return; | 468 return; |
469 } | 469 } |
470 | 470 |
471 // The classifications should always cover the whole string. | 471 // The classifications should always cover the whole string. |
472 DCHECK(!classifications.empty()) << "No classification for \"" << text << '"'; | 472 DCHECK(!classifications.empty()) << "No classification for \"" << text << '"'; |
473 DCHECK_EQ(0U, classifications[0].offset) | 473 DCHECK_EQ(0U, classifications[0].offset) |
474 << "Classification misses beginning for \"" << text << '"'; | 474 << "Classification misses beginning for \"" << text << '"'; |
(...skipping 10 matching lines...) Expand all Loading... |
485 << " is unsorted in relation to last offset of " << last_offset | 485 << " is unsorted in relation to last offset of " << last_offset |
486 << ". Provider: " << provider_name << "."; | 486 << ". Provider: " << provider_name << "."; |
487 DCHECK_LT(i->offset, text.length()) | 487 DCHECK_LT(i->offset, text.length()) |
488 << " Classification of [" << i->offset << "," << text.length() | 488 << " Classification of [" << i->offset << "," << text.length() |
489 << "] is out of bounds for \"" << text << "\". Provider: " | 489 << "] is out of bounds for \"" << text << "\". Provider: " |
490 << provider_name << "."; | 490 << provider_name << "."; |
491 last_offset = i->offset; | 491 last_offset = i->offset; |
492 } | 492 } |
493 } | 493 } |
494 #endif | 494 #endif |
OLD | NEW |