OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/search_provider.h" | 5 #include "chrome/browser/autocomplete/search_provider.h" |
6 | 6 |
7 #include "app/l10n_util.h" | 7 #include "app/l10n_util.h" |
8 #include "base/command_line.h" | |
9 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
10 #include "base/string_util.h" | 9 #include "base/string_util.h" |
11 #include "chrome/browser/autocomplete/keyword_provider.h" | 10 #include "chrome/browser/autocomplete/keyword_provider.h" |
12 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
13 #include "chrome/browser/google_util.h" | 12 #include "chrome/browser/google_util.h" |
14 #include "chrome/browser/history/history.h" | 13 #include "chrome/browser/history/history.h" |
15 #include "chrome/browser/net/url_fixer_upper.h" | 14 #include "chrome/browser/net/url_fixer_upper.h" |
16 #include "chrome/browser/profile.h" | 15 #include "chrome/browser/profile.h" |
17 #include "chrome/browser/search_engines/template_url_model.h" | 16 #include "chrome/browser/search_engines/template_url_model.h" |
18 #include "chrome/common/chrome_switches.h" | |
19 #include "chrome/common/json_value_serializer.h" | 17 #include "chrome/common/json_value_serializer.h" |
20 #include "chrome/common/pref_names.h" | 18 #include "chrome/common/pref_names.h" |
21 #include "chrome/common/pref_service.h" | 19 #include "chrome/common/pref_service.h" |
22 #include "chrome/common/url_constants.h" | 20 #include "chrome/common/url_constants.h" |
23 #include "googleurl/src/url_util.h" | 21 #include "googleurl/src/url_util.h" |
24 #include "grit/generated_resources.h" | 22 #include "grit/generated_resources.h" |
25 #include "net/base/escape.h" | 23 #include "net/base/escape.h" |
26 #include "net/http/http_response_headers.h" | 24 #include "net/http/http_response_headers.h" |
27 #include "net/url_request/url_request_status.h" | 25 #include "net/url_request/url_request_status.h" |
28 | 26 |
(...skipping 634 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
663 AutocompleteMatch::Type type, | 661 AutocompleteMatch::Type type, |
664 int accepted_suggestion, | 662 int accepted_suggestion, |
665 bool is_keyword, | 663 bool is_keyword, |
666 MatchMap* map) { | 664 MatchMap* map) { |
667 const std::wstring& input_text = | 665 const std::wstring& input_text = |
668 is_keyword ? keyword_input_text_ : input_.text(); | 666 is_keyword ? keyword_input_text_ : input_.text(); |
669 AutocompleteMatch match(this, relevance, false, type); | 667 AutocompleteMatch match(this, relevance, false, type); |
670 std::vector<size_t> content_param_offsets; | 668 std::vector<size_t> content_param_offsets; |
671 const TemplateURL& provider = is_keyword ? providers_.keyword_provider() : | 669 const TemplateURL& provider = is_keyword ? providers_.keyword_provider() : |
672 providers_.default_provider(); | 670 providers_.default_provider(); |
673 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableOmnibox2)) { | 671 // We do intra-string highlighting for suggestions - the suggested segment |
674 match.contents.assign(l10n_util::GetStringF( | 672 // will be highlighted, e.g. for input_text = "you" the suggestion may be |
675 IDS_AUTOCOMPLETE_SEARCH_CONTENTS, | 673 // "youtube", so we'll bold the "tube" section: you*tube*. |
676 provider.short_name(), | 674 if (input_text != query_string) { |
677 query_string, | 675 match.contents.assign(query_string); |
678 &content_param_offsets)); | 676 size_t input_position = match.contents.find(input_text); |
679 if (content_param_offsets.size() == 2) { | 677 if (input_position == std::wstring::npos) { |
680 AutocompleteMatch::ClassifyLocationInString(content_param_offsets[1], | 678 // The input text is not a substring of the query string, e.g. input |
681 query_string.length(), | 679 // text is "slasdot" and the query string is "slashdot", so we bold the |
682 match.contents.length(), | 680 // whole thing. |
683 ACMatchClassification::NONE, | 681 match.contents_class.push_back( |
684 &match.contents_class); | 682 ACMatchClassification(0, ACMatchClassification::MATCH)); |
685 } else { | 683 } else { |
686 // |content_param_offsets| should only not be 2 if: | 684 // TODO(beng): ACMatchClassification::MATCH now seems to just mean |
687 // (a) A translator screws up | 685 // "bold" this. Consider modifying the terminology. |
688 // (b) The strings have been changed and we haven't been rebuilt properly | 686 // We don't iterate over the string here annotating all matches because |
689 // (c) Some sort of crazy installer error/DLL version mismatch problem | 687 // it looks odd to have every occurrence of a substring that may be as |
690 // that gets the wrong data out of the locale DLL? | 688 // short as a single character highlighted in a query suggestion result, |
691 // While none of these are supposed to happen, we've seen this get hit in | 689 // e.g. for input text "s" and query string "southwest airlines", it |
692 // the wild, so avoid the vector access in the conditional arm above, | 690 // looks odd if both the first and last s are highlighted. |
693 // which will crash. | 691 if (input_position != 0) { |
694 NOTREACHED(); | 692 match.contents_class.push_back( |
| 693 ACMatchClassification(0, ACMatchClassification::NONE)); |
| 694 } |
| 695 match.contents_class.push_back( |
| 696 ACMatchClassification(input_position, ACMatchClassification::DIM)); |
| 697 size_t next_fragment_position = input_position + input_text.length(); |
| 698 if (next_fragment_position < query_string.length()) { |
| 699 match.contents_class.push_back( |
| 700 ACMatchClassification(next_fragment_position, |
| 701 ACMatchClassification::NONE)); |
| 702 } |
695 } | 703 } |
696 } else { | 704 } else { |
697 // We do intra-string highlighting for suggestions - the suggested segment | 705 // Otherwise, we're dealing with the "default search" result which has no |
698 // will be highlighted, e.g. for input_text = "you" the suggestion may be | 706 // completion, but has the search provider name as the description. |
699 // "youtube", so we'll bold the "tube" section: you*tube*. | 707 match.contents.assign(query_string); |
700 if (input_text != query_string) { | 708 match.contents_class.push_back( |
701 match.contents.assign(query_string); | 709 ACMatchClassification(0, ACMatchClassification::NONE)); |
702 size_t input_position = match.contents.find(input_text); | 710 match.description.assign(l10n_util::GetStringF( |
703 if (input_position == std::wstring::npos) { | 711 IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION, |
704 // The input text is not a substring of the query string, e.g. input | 712 provider.short_name())); |
705 // text is "slasdot" and the query string is "slashdot", so we bold the | 713 match.description_class.push_back( |
706 // whole thing. | 714 ACMatchClassification(0, ACMatchClassification::DIM)); |
707 match.contents_class.push_back( | |
708 ACMatchClassification(0, ACMatchClassification::MATCH)); | |
709 } else { | |
710 // TODO(beng): ACMatchClassification::MATCH now seems to just mean | |
711 // "bold" this. Consider modifying the terminology. | |
712 // We don't iterate over the string here annotating all matches because | |
713 // it looks odd to have every occurrence of a substring that may be as | |
714 // short as a single character highlighted in a query suggestion result, | |
715 // e.g. for input text "s" and query string "southwest airlines", it | |
716 // looks odd if both the first and last s are highlighted. | |
717 if (input_position != 0) { | |
718 match.contents_class.push_back( | |
719 ACMatchClassification(0, ACMatchClassification::NONE)); | |
720 } | |
721 match.contents_class.push_back( | |
722 ACMatchClassification(input_position, ACMatchClassification::DIM)); | |
723 size_t next_fragment_position = input_position + input_text.length(); | |
724 if (next_fragment_position < query_string.length()) { | |
725 match.contents_class.push_back( | |
726 ACMatchClassification(next_fragment_position, | |
727 ACMatchClassification::NONE)); | |
728 } | |
729 } | |
730 } else { | |
731 // Otherwise, we're dealing with the "default search" result which has no | |
732 // completion, but has the search provider name as the description. | |
733 match.contents.assign(query_string); | |
734 match.contents_class.push_back( | |
735 ACMatchClassification(0, ACMatchClassification::NONE)); | |
736 match.description.assign(l10n_util::GetStringF( | |
737 IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION, | |
738 provider.short_name())); | |
739 match.description_class.push_back( | |
740 ACMatchClassification(0, ACMatchClassification::DIM)); | |
741 } | |
742 } | 715 } |
743 | 716 |
744 // When the user forced a query, we need to make sure all the fill_into_edit | 717 // When the user forced a query, we need to make sure all the fill_into_edit |
745 // values preserve that property. Otherwise, if the user starts editing a | 718 // values preserve that property. Otherwise, if the user starts editing a |
746 // suggestion, non-Search results will suddenly appear. | 719 // suggestion, non-Search results will suddenly appear. |
747 size_t search_start = 0; | 720 size_t search_start = 0; |
748 if (input_.type() == AutocompleteInput::FORCED_QUERY) { | 721 if (input_.type() == AutocompleteInput::FORCED_QUERY) { |
749 match.fill_into_edit.assign(L"?"); | 722 match.fill_into_edit.assign(L"?"); |
750 ++search_start; | 723 ++search_start; |
751 } | 724 } |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
816 // values preserve that property. Otherwise, if the user starts editing a | 789 // values preserve that property. Otherwise, if the user starts editing a |
817 // suggestion, non-Search results will suddenly appear. | 790 // suggestion, non-Search results will suddenly appear. |
818 if (input_.type() == AutocompleteInput::FORCED_QUERY) | 791 if (input_.type() == AutocompleteInput::FORCED_QUERY) |
819 match.fill_into_edit.assign(L"?"); | 792 match.fill_into_edit.assign(L"?"); |
820 match.fill_into_edit.append(match.contents); | 793 match.fill_into_edit.append(match.contents); |
821 // TODO(pkasting): http://b/1112879 These should perhaps be | 794 // TODO(pkasting): http://b/1112879 These should perhaps be |
822 // inline-autocompletable? | 795 // inline-autocompletable? |
823 | 796 |
824 return match; | 797 return match; |
825 } | 798 } |
OLD | NEW |