OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "components/omnibox/autocomplete_match.h" | 5 #include "components/omnibox/autocomplete_match.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/i18n/time_formatting.h" | 8 #include "base/i18n/time_formatting.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/string16.h" | 10 #include "base/strings/string16.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "grit/components_scaled_resources.h" | 21 #include "grit/components_scaled_resources.h" |
22 | 22 |
23 namespace { | 23 namespace { |
24 | 24 |
25 bool IsTrivialClassification(const ACMatchClassifications& classifications) { | 25 bool IsTrivialClassification(const ACMatchClassifications& classifications) { |
26 return classifications.empty() || | 26 return classifications.empty() || |
27 ((classifications.size() == 1) && | 27 ((classifications.size() == 1) && |
28 (classifications.back().style == ACMatchClassification::NONE)); | 28 (classifications.back().style == ACMatchClassification::NONE)); |
29 } | 29 } |
30 | 30 |
| 31 // Returns true if one of the |terms_prefixed_by_http_or_https| matches the |
| 32 // beginning of the URL (sans scheme). (Recall that |
| 33 // |terms_prefixed_by_http_or_https|, for the input "http://a b" will be |
| 34 // ["a"].) This suggests that the user wants a particular URL with a scheme |
| 35 // in mind, hence the caller should not consider another URL like this one |
| 36 // but with a different scheme to be a duplicate. |
| 37 bool WordMatchesURLContent( |
| 38 const std::vector<std::string>& terms_prefixed_by_http_or_https, |
| 39 const GURL& url) { |
| 40 const size_t prefix_length = |
| 41 url.scheme().length() + strlen(url::kStandardSchemeSeparator); |
| 42 DCHECK_GE(url.spec().length(), prefix_length); |
| 43 const std::string& url_spec_without_scheme = url.spec().substr(prefix_length); |
| 44 for (const auto& term : terms_prefixed_by_http_or_https) { |
| 45 if (base::StartsWith(url_spec_without_scheme, term, |
| 46 base::CompareCase::INSENSITIVE_ASCII)) |
| 47 return true; |
| 48 } |
| 49 return false; |
| 50 } |
| 51 |
31 } // namespace | 52 } // namespace |
32 | 53 |
33 // AutocompleteMatch ---------------------------------------------------------- | 54 // AutocompleteMatch ---------------------------------------------------------- |
34 | 55 |
35 // static | 56 // static |
36 const base::char16 AutocompleteMatch::kInvalidChars[] = { | 57 const base::char16 AutocompleteMatch::kInvalidChars[] = { |
37 '\n', '\r', '\t', | 58 '\n', '\r', '\t', |
38 0x2028, // Line separator | 59 0x2028, // Line separator |
39 0x2029, // Paragraph separator | 60 0x2029, // Paragraph separator |
40 0 | 61 0 |
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 return NULL; | 386 return NULL; |
366 TemplateURL* template_url = keyword.empty() ? | 387 TemplateURL* template_url = keyword.empty() ? |
367 NULL : template_url_service->GetTemplateURLForKeyword(keyword); | 388 NULL : template_url_service->GetTemplateURLForKeyword(keyword); |
368 return (template_url || host.empty()) ? | 389 return (template_url || host.empty()) ? |
369 template_url : template_url_service->GetTemplateURLForHost(host); | 390 template_url : template_url_service->GetTemplateURLForHost(host); |
370 } | 391 } |
371 | 392 |
372 // static | 393 // static |
373 GURL AutocompleteMatch::GURLToStrippedGURL( | 394 GURL AutocompleteMatch::GURLToStrippedGURL( |
374 const GURL& url, | 395 const GURL& url, |
| 396 const AutocompleteInput& input, |
375 TemplateURLService* template_url_service, | 397 TemplateURLService* template_url_service, |
376 const base::string16& keyword) { | 398 const base::string16& keyword) { |
377 if (!url.is_valid()) | 399 if (!url.is_valid()) |
378 return url; | 400 return url; |
379 | 401 |
380 GURL stripped_destination_url = url; | 402 GURL stripped_destination_url = url; |
381 | 403 |
382 // If the destination URL looks like it was generated from a TemplateURL, | 404 // If the destination URL looks like it was generated from a TemplateURL, |
383 // remove all substitutions other than the search terms. This allows us | 405 // remove all substitutions other than the search terms. This allows us |
384 // to eliminate cases like past search URLs from history that differ only | 406 // to eliminate cases like past search URLs from history that differ only |
(...skipping 25 matching lines...) Expand all Loading... |
410 | 432 |
411 // Remove the www. prefix from the host. | 433 // Remove the www. prefix from the host. |
412 static const char prefix[] = "www."; | 434 static const char prefix[] = "www."; |
413 static const size_t prefix_len = arraysize(prefix) - 1; | 435 static const size_t prefix_len = arraysize(prefix) - 1; |
414 std::string host = stripped_destination_url.host(); | 436 std::string host = stripped_destination_url.host(); |
415 if (host.compare(0, prefix_len, prefix) == 0) { | 437 if (host.compare(0, prefix_len, prefix) == 0) { |
416 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len)); | 438 replacements.SetHostStr(base::StringPiece(host).substr(prefix_len)); |
417 needs_replacement = true; | 439 needs_replacement = true; |
418 } | 440 } |
419 | 441 |
420 // Replace https protocol with http protocol. | 442 // Remove any trailing slash (if it's not a lone slash), or add a slash (to |
421 if (stripped_destination_url.SchemeIs(url::kHttpsScheme)) { | 443 // make a lone slash) if the path is empty. (We can't unconditionally |
| 444 // remove even lone slashes because for some schemes the path must consist |
| 445 // of at least a slash.) |
| 446 const std::string& path = stripped_destination_url.path(); |
| 447 if ((path.length() > 1) && (path[path.length() - 1] == '/')) { |
| 448 replacements.SetPathStr( |
| 449 base::StringPiece(path).substr(0, path.length() - 1)); |
| 450 needs_replacement = true; |
| 451 } else if (path.empty()) { |
| 452 static const char slash[] = "/"; |
| 453 replacements.SetPathStr(base::StringPiece(slash)); |
| 454 needs_replacement = true; |
| 455 } |
| 456 |
| 457 // Replace https protocol with http, as long as the user didn't explicitly |
| 458 // specify one of the two. |
| 459 if (stripped_destination_url.SchemeIs(url::kHttpsScheme) && |
| 460 (input.terms_prefixed_by_http_or_https().empty() || |
| 461 !WordMatchesURLContent(input.terms_prefixed_by_http_or_https(), url))) { |
422 replacements.SetScheme(url::kHttpScheme, | 462 replacements.SetScheme(url::kHttpScheme, |
423 url::Component(0, strlen(url::kHttpScheme))); | 463 url::Component(0, strlen(url::kHttpScheme))); |
424 needs_replacement = true; | 464 needs_replacement = true; |
425 } | 465 } |
426 | 466 |
427 if (needs_replacement) | 467 if (needs_replacement) |
428 stripped_destination_url = stripped_destination_url.ReplaceComponents( | 468 stripped_destination_url = stripped_destination_url.ReplaceComponents( |
429 replacements); | 469 replacements); |
430 return stripped_destination_url; | 470 return stripped_destination_url; |
431 } | 471 } |
432 | 472 |
433 void AutocompleteMatch::ComputeStrippedDestinationURL( | 473 void AutocompleteMatch::ComputeStrippedDestinationURL( |
| 474 const AutocompleteInput& input, |
434 TemplateURLService* template_url_service) { | 475 TemplateURLService* template_url_service) { |
435 stripped_destination_url = | 476 stripped_destination_url = GURLToStrippedGURL( |
436 GURLToStrippedGURL(destination_url, template_url_service, keyword); | 477 destination_url, input, template_url_service, keyword); |
437 } | 478 } |
438 | 479 |
439 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault( | 480 void AutocompleteMatch::EnsureUWYTIsAllowedToBeDefault( |
440 const GURL& canonical_input_url, | 481 const AutocompleteInput& input, |
441 TemplateURLService* template_url_service) { | 482 TemplateURLService* template_url_service) { |
442 if (!allowed_to_be_default_match) { | 483 if (!allowed_to_be_default_match) { |
443 const GURL& stripped_canonical_input_url = | 484 const GURL& stripped_canonical_input_url = |
444 AutocompleteMatch::GURLToStrippedGURL( | 485 AutocompleteMatch::GURLToStrippedGURL( |
445 canonical_input_url, template_url_service, base::string16()); | 486 input.canonicalized_url(), input, template_url_service, |
446 ComputeStrippedDestinationURL(template_url_service); | 487 base::string16()); |
| 488 ComputeStrippedDestinationURL(input, template_url_service); |
447 allowed_to_be_default_match = | 489 allowed_to_be_default_match = |
448 stripped_canonical_input_url == stripped_destination_url; | 490 stripped_canonical_input_url == stripped_destination_url; |
449 } | 491 } |
450 } | 492 } |
451 | 493 |
452 void AutocompleteMatch::GetKeywordUIState( | 494 void AutocompleteMatch::GetKeywordUIState( |
453 TemplateURLService* template_url_service, | 495 TemplateURLService* template_url_service, |
454 base::string16* keyword, | 496 base::string16* keyword, |
455 bool* is_keyword_hint) const { | 497 bool* is_keyword_hint) const { |
456 *is_keyword_hint = associated_keyword.get() != NULL; | 498 *is_keyword_hint = associated_keyword.get() != NULL; |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 << " is unsorted in relation to last offset of " << last_offset | 613 << " is unsorted in relation to last offset of " << last_offset |
572 << ". Provider: " << provider_name << "."; | 614 << ". Provider: " << provider_name << "."; |
573 DCHECK_LT(i->offset, text.length()) | 615 DCHECK_LT(i->offset, text.length()) |
574 << " Classification of [" << i->offset << "," << text.length() | 616 << " Classification of [" << i->offset << "," << text.length() |
575 << "] is out of bounds for \"" << text << "\". Provider: " | 617 << "] is out of bounds for \"" << text << "\". Provider: " |
576 << provider_name << "."; | 618 << provider_name << "."; |
577 last_offset = i->offset; | 619 last_offset = i->offset; |
578 } | 620 } |
579 } | 621 } |
580 #endif | 622 #endif |
OLD | NEW |