| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "components/autocomplete/autocomplete_provider.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "base/strings/utf_string_conversions.h" | |
| 9 #include "components/autocomplete/autocomplete_input.h" | |
| 10 #include "components/autocomplete/autocomplete_match.h" | |
| 11 #include "components/url_fixer/url_fixer.h" | |
| 12 #include "net/base/net_util.h" | |
| 13 #include "url/gurl.h" | |
| 14 | |
| 15 // static | |
| 16 const size_t AutocompleteProvider::kMaxMatches = 3; | |
| 17 | |
| 18 AutocompleteProvider::AutocompleteProvider(Type type) | |
| 19 : done_(true), | |
| 20 type_(type) { | |
| 21 } | |
| 22 | |
| 23 // static | |
| 24 const char* AutocompleteProvider::TypeToString(Type type) { | |
| 25 switch (type) { | |
| 26 case TYPE_BOOKMARK: | |
| 27 return "Bookmark"; | |
| 28 case TYPE_BUILTIN: | |
| 29 return "Builtin"; | |
| 30 case TYPE_HISTORY_QUICK: | |
| 31 return "HistoryQuick"; | |
| 32 case TYPE_HISTORY_URL: | |
| 33 return "HistoryURL"; | |
| 34 case TYPE_KEYWORD: | |
| 35 return "Keyword"; | |
| 36 case TYPE_SEARCH: | |
| 37 return "Search"; | |
| 38 case TYPE_SHORTCUTS: | |
| 39 return "Shortcuts"; | |
| 40 case TYPE_ZERO_SUGGEST: | |
| 41 return "ZeroSuggest"; | |
| 42 default: | |
| 43 NOTREACHED() << "Unhandled AutocompleteProvider::Type " << type; | |
| 44 return "Unknown"; | |
| 45 } | |
| 46 } | |
| 47 | |
| 48 void AutocompleteProvider::Stop(bool clear_cached_results) { | |
| 49 done_ = true; | |
| 50 } | |
| 51 | |
| 52 const char* AutocompleteProvider::GetName() const { | |
| 53 return TypeToString(type_); | |
| 54 } | |
| 55 | |
| 56 metrics::OmniboxEventProto_ProviderType AutocompleteProvider:: | |
| 57 AsOmniboxEventProviderType() const { | |
| 58 switch (type_) { | |
| 59 case TYPE_BOOKMARK: | |
| 60 return metrics::OmniboxEventProto::BOOKMARK; | |
| 61 case TYPE_BUILTIN: | |
| 62 return metrics::OmniboxEventProto::BUILTIN; | |
| 63 case TYPE_HISTORY_QUICK: | |
| 64 return metrics::OmniboxEventProto::HISTORY_QUICK; | |
| 65 case TYPE_HISTORY_URL: | |
| 66 return metrics::OmniboxEventProto::HISTORY_URL; | |
| 67 case TYPE_KEYWORD: | |
| 68 return metrics::OmniboxEventProto::KEYWORD; | |
| 69 case TYPE_SEARCH: | |
| 70 return metrics::OmniboxEventProto::SEARCH; | |
| 71 case TYPE_SHORTCUTS: | |
| 72 return metrics::OmniboxEventProto::SHORTCUTS; | |
| 73 case TYPE_ZERO_SUGGEST: | |
| 74 return metrics::OmniboxEventProto::ZERO_SUGGEST; | |
| 75 default: | |
| 76 NOTREACHED() << "Unhandled AutocompleteProvider::Type " << type_; | |
| 77 return metrics::OmniboxEventProto::UNKNOWN_PROVIDER; | |
| 78 } | |
| 79 } | |
| 80 | |
| 81 void AutocompleteProvider::DeleteMatch(const AutocompleteMatch& match) { | |
| 82 DLOG(WARNING) << "The AutocompleteProvider '" << GetName() | |
| 83 << "' has not implemented DeleteMatch."; | |
| 84 } | |
| 85 | |
| 86 void AutocompleteProvider::AddProviderInfo(ProvidersInfo* provider_info) const { | |
| 87 } | |
| 88 | |
| 89 void AutocompleteProvider::ResetSession() { | |
| 90 } | |
| 91 | |
| 92 AutocompleteProvider::~AutocompleteProvider() { | |
| 93 Stop(false); | |
| 94 } | |
| 95 | |
| 96 // static | |
| 97 AutocompleteProvider::FixupReturn AutocompleteProvider::FixupUserInput( | |
| 98 const AutocompleteInput& input) { | |
| 99 const base::string16& input_text = input.text(); | |
| 100 const FixupReturn failed(false, input_text); | |
| 101 | |
| 102 // Fixup and canonicalize user input. | |
| 103 const GURL canonical_gurl( | |
| 104 url_fixer::FixupURL(base::UTF16ToUTF8(input_text), std::string())); | |
| 105 std::string canonical_gurl_str(canonical_gurl.possibly_invalid_spec()); | |
| 106 if (canonical_gurl_str.empty()) { | |
| 107 // This probably won't happen, but there are no guarantees. | |
| 108 return failed; | |
| 109 } | |
| 110 | |
| 111 // If the user types a number, GURL will convert it to a dotted quad. | |
| 112 // However, if the parser did not mark this as a URL, then the user probably | |
| 113 // didn't intend this interpretation. Since this can break history matching | |
| 114 // for hostname beginning with numbers (e.g. input of "17173" will be matched | |
| 115 // against "0.0.67.21" instead of the original "17173", failing to find | |
| 116 // "17173.com"), swap the original hostname in for the fixed-up one. | |
| 117 if ((input.type() != metrics::OmniboxInputType::URL) && | |
| 118 canonical_gurl.HostIsIPAddress()) { | |
| 119 std::string original_hostname = | |
| 120 base::UTF16ToUTF8(input_text.substr(input.parts().host.begin, | |
| 121 input.parts().host.len)); | |
| 122 const url::Parsed& parts = | |
| 123 canonical_gurl.parsed_for_possibly_invalid_spec(); | |
| 124 // parts.host must not be empty when HostIsIPAddress() is true. | |
| 125 DCHECK(parts.host.is_nonempty()); | |
| 126 canonical_gurl_str.replace(parts.host.begin, parts.host.len, | |
| 127 original_hostname); | |
| 128 } | |
| 129 base::string16 output(base::UTF8ToUTF16(canonical_gurl_str)); | |
| 130 // Don't prepend a scheme when the user didn't have one. Since the fixer | |
| 131 // upper only prepends the "http" scheme, that's all we need to check for. | |
| 132 if (!AutocompleteInput::HasHTTPScheme(input_text)) | |
| 133 TrimHttpPrefix(&output); | |
| 134 | |
| 135 // Make the number of trailing slashes on the output exactly match the input. | |
| 136 // Examples of why not doing this would matter: | |
| 137 // * The user types "a" and has this fixed up to "a/". Now no other sites | |
| 138 // beginning with "a" will match. | |
| 139 // * The user types "file:" and has this fixed up to "file://". Now inline | |
| 140 // autocomplete will append too few slashes, resulting in e.g. "file:/b..." | |
| 141 // instead of "file:///b..." | |
| 142 // * The user types "http:/" and has this fixed up to "http:". Now inline | |
| 143 // autocomplete will append too many slashes, resulting in e.g. | |
| 144 // "http:///c..." instead of "http://c...". | |
| 145 // NOTE: We do this after calling TrimHttpPrefix() since that can strip | |
| 146 // trailing slashes (if the scheme is the only thing in the input). It's not | |
| 147 // clear that the result of fixup really matters in this case, but there's no | |
| 148 // harm in making sure. | |
| 149 const size_t last_input_nonslash = | |
| 150 input_text.find_last_not_of(base::ASCIIToUTF16("/\\")); | |
| 151 const size_t num_input_slashes = | |
| 152 (last_input_nonslash == base::string16::npos) ? | |
| 153 input_text.length() : (input_text.length() - 1 - last_input_nonslash); | |
| 154 const size_t last_output_nonslash = | |
| 155 output.find_last_not_of(base::ASCIIToUTF16("/\\")); | |
| 156 const size_t num_output_slashes = | |
| 157 (last_output_nonslash == base::string16::npos) ? | |
| 158 output.length() : (output.length() - 1 - last_output_nonslash); | |
| 159 if (num_output_slashes < num_input_slashes) | |
| 160 output.append(num_input_slashes - num_output_slashes, '/'); | |
| 161 else if (num_output_slashes > num_input_slashes) | |
| 162 output.erase(output.length() - num_output_slashes + num_input_slashes); | |
| 163 if (output.empty()) | |
| 164 return failed; | |
| 165 | |
| 166 return FixupReturn(true, output); | |
| 167 } | |
| 168 | |
| 169 // static | |
| 170 size_t AutocompleteProvider::TrimHttpPrefix(base::string16* url) { | |
| 171 // Find any "http:". | |
| 172 if (!AutocompleteInput::HasHTTPScheme(*url)) | |
| 173 return 0; | |
| 174 size_t scheme_pos = | |
| 175 url->find(base::ASCIIToUTF16(url::kHttpScheme) + base::char16(':')); | |
| 176 DCHECK_NE(base::string16::npos, scheme_pos); | |
| 177 | |
| 178 // Erase scheme plus up to two slashes. | |
| 179 size_t prefix_end = scheme_pos + strlen(url::kHttpScheme) + 1; | |
| 180 const size_t after_slashes = std::min(url->length(), prefix_end + 2); | |
| 181 while ((prefix_end < after_slashes) && ((*url)[prefix_end] == '/')) | |
| 182 ++prefix_end; | |
| 183 url->erase(scheme_pos, prefix_end - scheme_pos); | |
| 184 return (scheme_pos == 0) ? prefix_end : 0; | |
| 185 } | |
| OLD | NEW |