15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_provider.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_match.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/autocomplete/autocomplete_provider_listener.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h" 15f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)#include "chrome/common/net/url_fixer_upper.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/url_constants.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_util.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t AutocompleteProvider::kMaxMatches = 3; 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteProvider::AutocompleteProvider( 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteProviderListener* listener, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile, 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Type type) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : profile_(profile), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_(listener), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_(true), 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) type_(type) { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* AutocompleteProvider::TypeToString(Type type) { 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type) { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_BOOKMARK: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Bookmark"; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_BUILTIN: 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Builtin"; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_CONTACT: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Contact"; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_EXTENSION_APP: 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "ExtensionApp"; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_HISTORY_QUICK: 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "HistoryQuick"; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_HISTORY_URL: 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "HistoryURL"; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_KEYWORD: 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Keyword"; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_SEARCH: 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Search"; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_SHORTCUTS: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Shortcuts"; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_ZERO_SUGGEST: 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "ZeroSuggest"; 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unhandled AutocompleteProvider::Type " << type; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "Unknown"; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteProvider::Stop(bool clear_cached_results) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_ = true; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* AutocompleteProvider::GetName() const { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return TypeToString(type_); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)metrics::OmniboxEventProto_ProviderType AutocompleteProvider:: 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AsOmniboxEventProviderType() const { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (type_) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_BOOKMARK: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::BOOKMARK; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_BUILTIN: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::BUILTIN; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_CONTACT: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::CONTACT; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_EXTENSION_APP: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::EXTENSION_APPS; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_HISTORY_QUICK: 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::HISTORY_QUICK; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_HISTORY_URL: 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::HISTORY_URL; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_KEYWORD: 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::KEYWORD; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_SEARCH: 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::SEARCH; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_SHORTCUTS: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::SHORTCUTS; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case TYPE_ZERO_SUGGEST: 93c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return metrics::OmniboxEventProto::ZERO_SUGGEST; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unhandled AutocompleteProvider::Type " << type_; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return metrics::OmniboxEventProto::UNKNOWN_PROVIDER; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteProvider::DeleteMatch(const AutocompleteMatch& match) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG(WARNING) << "The AutocompleteProvider '" << GetName() 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "' has not implemented DeleteMatch."; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteProvider::AddProviderInfo(ProvidersInfo* provider_info) const { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AutocompleteProvider::ResetSession() { 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)base::string16 AutocompleteProvider::StringForURLDisplay(const GURL& url, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool check_accept_lang, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool trim_http) const { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string languages = (check_accept_lang && profile_) ? 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) profile_->GetPrefs()->GetString(prefs::kAcceptLanguages) : std::string(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return net::FormatUrl(url, languages, 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::kFormatUrlOmitAll & ~(trim_http ? 0 : net::kFormatUrlOmitHTTP), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::UnescapeRule::SPACES, NULL, NULL, NULL); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteProvider::~AutocompleteProvider() { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(false); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteProvider::UpdateStarredStateOfMatches() { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (matches_.empty()) 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!profile_) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BookmarkModel* bookmark_model = BookmarkModelFactory::GetForProfile(profile_); 133b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (!bookmark_model || !bookmark_model->loaded()) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ACMatches::iterator i(matches_.begin()); i != matches_.end(); ++i) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->starred = bookmark_model->IsBookmarked(i->destination_url); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 139f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) 140f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)// static 141f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)bool AutocompleteProvider::FixupUserInput(AutocompleteInput* input) { 142f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const base::string16& input_text = input->text(); 143f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // Fixup and canonicalize user input. 144f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const GURL canonical_gurl(URLFixerUpper::FixupURL(UTF16ToUTF8(input_text), 145f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) std::string())); 146f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) std::string canonical_gurl_str(canonical_gurl.possibly_invalid_spec()); 147f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) if (canonical_gurl_str.empty()) { 148f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // This probably won't happen, but there are no guarantees. 149f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) return false; 150f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) } 151f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) 152f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // If the user types a number, GURL will convert it to a dotted quad. 153f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // However, if the parser did not mark this as a URL, then the user probably 154f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // didn't intend this interpretation. Since this can break history matching 155f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // for hostname beginning with numbers (e.g. input of "17173" will be matched 156f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // against "0.0.67.21" instead of the original "17173", failing to find 157f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // "17173.com"), swap the original hostname in for the fixed-up one. 158f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) if ((input->type() != AutocompleteInput::URL) && 159f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) canonical_gurl.HostIsIPAddress()) { 160f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) std::string original_hostname = 161f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) UTF16ToUTF8(input_text.substr(input->parts().host.begin, 162f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) input->parts().host.len)); 163f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const url_parse::Parsed& parts = 164f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) canonical_gurl.parsed_for_possibly_invalid_spec(); 165f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // parts.host must not be empty when HostIsIPAddress() is true. 166f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) DCHECK(parts.host.is_nonempty()); 167f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) canonical_gurl_str.replace(parts.host.begin, parts.host.len, 168f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) original_hostname); 169f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) } 170f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) base::string16 output = UTF8ToUTF16(canonical_gurl_str); 171f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // Don't prepend a scheme when the user didn't have one. Since the fixer 172f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // upper only prepends the "http" scheme, that's all we need to check for. 173f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) if (!AutocompleteInput::HasHTTPScheme(input_text)) 174f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) TrimHttpPrefix(&output); 175f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) 176f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // Make the number of trailing slashes on the output exactly match the input. 177f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // Examples of why not doing this would matter: 178f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // * The user types "a" and has this fixed up to "a/". Now no other sites 179f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // beginning with "a" will match. 180f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // * The user types "file:" and has this fixed up to "file://". Now inline 181f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // autocomplete will append too few slashes, resulting in e.g. "file:/b..." 182f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // instead of "file:///b..." 183f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // * The user types "http:/" and has this fixed up to "http:". Now inline 184f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // autocomplete will append too many slashes, resulting in e.g. 185f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // "http:///c..." instead of "http://c...". 186f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // NOTE: We do this after calling TrimHttpPrefix() since that can strip 187f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // trailing slashes (if the scheme is the only thing in the input). It's not 188f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // clear that the result of fixup really matters in this case, but there's no 189f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // harm in making sure. 190f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const size_t last_input_nonslash = 191f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) input_text.find_last_not_of(ASCIIToUTF16("/\\")); 192f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const size_t num_input_slashes = 193f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) (last_input_nonslash == base::string16::npos) ? 194f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) input_text.length() : (input_text.length() - 1 - last_input_nonslash); 195f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const size_t last_output_nonslash = 196f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) output.find_last_not_of(ASCIIToUTF16("/\\")); 197f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const size_t num_output_slashes = 198f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) (last_output_nonslash == base::string16::npos) ? 199f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) output.length() : (output.length() - 1 - last_output_nonslash); 200f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) if (num_output_slashes < num_input_slashes) 201f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) output.append(num_input_slashes - num_output_slashes, '/'); 202f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) else if (num_output_slashes > num_input_slashes) 203f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) output.erase(output.length() - num_output_slashes + num_input_slashes); 204f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) 205f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) url_parse::Parsed parts; 206f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) URLFixerUpper::SegmentURL(output, &parts); 207f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) input->UpdateText(output, base::string16::npos, parts); 208f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) return !output.empty(); 209f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)} 210f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) 211f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)// static 212f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)size_t AutocompleteProvider::TrimHttpPrefix(base::string16* url) { 213f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // Find any "http:". 214f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) if (!AutocompleteInput::HasHTTPScheme(*url)) 215f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) return 0; 216f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) size_t scheme_pos = 217f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) url->find(ASCIIToUTF16(content::kHttpScheme) + char16(':')); 218f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) DCHECK_NE(base::string16::npos, scheme_pos); 219f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) 220f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) // Erase scheme plus up to two slashes. 221f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) size_t prefix_end = scheme_pos + strlen(content::kHttpScheme) + 1; 222f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) const size_t after_slashes = std::min(url->length(), prefix_end + 2); 223f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) while ((prefix_end < after_slashes) && ((*url)[prefix_end] == '/')) 224f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) ++prefix_end; 225f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) url->erase(scheme_pos, prefix_end - scheme_pos); 226f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) return (scheme_pos == 0) ? prefix_end : 0; 227f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles)} 228f60fc993c7b081abf77ce2ffc7fcca1142c8cb01Torne (Richard Coles) 229