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 3 // found in the LICENSE file. 4 5 #include "chrome/browser/autocomplete/builtin_provider.h" 6 7 #include <algorithm> 8 9 #include "base/strings/string_util.h" 10 #include "base/strings/utf_string_conversions.h" 11 #include "chrome/browser/autocomplete/autocomplete_input.h" 12 #include "chrome/common/net/url_fixer_upper.h" 13 #include "chrome/common/url_constants.h" 14 15 namespace { 16 17 // This list should be kept in sync with chrome/common/url_constants.h. 18 // Only include useful sub-pages, confirmation alerts are not useful. 19 const char* const kChromeSettingsSubPages[] = { 20 chrome::kAutofillSubPage, 21 chrome::kClearBrowserDataSubPage, 22 chrome::kContentSettingsSubPage, 23 chrome::kContentSettingsExceptionsSubPage, 24 chrome::kImportDataSubPage, 25 chrome::kLanguageOptionsSubPage, 26 chrome::kPasswordManagerSubPage, 27 chrome::kSearchEnginesSubPage, 28 chrome::kSyncSetupSubPage, 29 #if defined(OS_CHROMEOS) 30 chrome::kInternetOptionsSubPage, 31 #endif 32 }; 33 34 } // namespace 35 36 const int BuiltinProvider::kRelevance = 860; 37 38 BuiltinProvider::BuiltinProvider(AutocompleteProviderListener* listener, 39 Profile* profile) 40 : AutocompleteProvider(listener, profile, 41 AutocompleteProvider::TYPE_BUILTIN) { 42 std::vector<std::string> builtins( 43 chrome::kChromeHostURLs, 44 chrome::kChromeHostURLs + chrome::kNumberOfChromeHostURLs); 45 std::sort(builtins.begin(), builtins.end()); 46 for (std::vector<std::string>::iterator i(builtins.begin()); 47 i != builtins.end(); ++i) 48 builtins_.push_back(ASCIIToUTF16(*i)); 49 string16 settings(ASCIIToUTF16(chrome::kChromeUISettingsHost) + 50 ASCIIToUTF16("/")); 51 for (size_t i = 0; i < arraysize(kChromeSettingsSubPages); i++) 52 builtins_.push_back(settings + ASCIIToUTF16(kChromeSettingsSubPages[i])); 53 } 54 55 void BuiltinProvider::Start(const AutocompleteInput& input, 56 bool minimal_changes) { 57 matches_.clear(); 58 if ((input.type() == AutocompleteInput::INVALID) || 59 (input.type() == AutocompleteInput::FORCED_QUERY) || 60 (input.type() == AutocompleteInput::QUERY) || 61 (input.matches_requested() == AutocompleteInput::BEST_MATCH)) 62 return; 63 64 const string16 kAbout = ASCIIToUTF16(chrome::kAboutScheme) + 65 ASCIIToUTF16(content::kStandardSchemeSeparator); 66 const string16 kChrome = ASCIIToUTF16(chrome::kChromeUIScheme) + 67 ASCIIToUTF16(content::kStandardSchemeSeparator); 68 69 const int kUrl = ACMatchClassification::URL; 70 const int kMatch = kUrl | ACMatchClassification::MATCH; 71 72 string16 text = input.text(); 73 bool starting_chrome = StartsWith(kChrome, text, false); 74 if (starting_chrome || StartsWith(kAbout, text, false)) { 75 ACMatchClassifications styles; 76 // Highlight the input portion matching "chrome://"; or if the user has 77 // input "about:" (with optional slashes), highlight the whole "chrome://". 78 const size_t kAboutSchemeLength = strlen(chrome::kAboutScheme); 79 bool highlight = starting_chrome || text.length() > kAboutSchemeLength; 80 styles.push_back(ACMatchClassification(0, highlight ? kMatch : kUrl)); 81 size_t offset = starting_chrome ? text.length() : kChrome.length(); 82 if (highlight) 83 styles.push_back(ACMatchClassification(offset, kUrl)); 84 // Include some common builtin chrome URLs as the user types the scheme. 85 AddMatch(ASCIIToUTF16(chrome::kChromeUIChromeURLsURL), styles); 86 AddMatch(ASCIIToUTF16(chrome::kChromeUISettingsURL), styles); 87 AddMatch(ASCIIToUTF16(chrome::kChromeUIVersionURL), styles); 88 } else { 89 // Match input about: or chrome: URL input against builtin chrome URLs. 90 GURL url = URLFixerUpper::FixupURL(UTF16ToUTF8(text), std::string()); 91 if (url.SchemeIs(chrome::kChromeUIScheme) && url.has_host()) { 92 // Include the path for sub-pages (e.g. "chrome://settings/browser"). 93 string16 host_and_path = UTF8ToUTF16(url.host() + url.path()); 94 TrimString(host_and_path, ASCIIToUTF16("/").c_str(), &host_and_path); 95 size_t match_length = kChrome.length() + host_and_path.length(); 96 for (Builtins::const_iterator i(builtins_.begin()); 97 (i != builtins_.end()) && (matches_.size() < kMaxMatches); ++i) { 98 if (StartsWith(*i, host_and_path, false)) { 99 ACMatchClassifications styles; 100 // Highlight the "chrome://" scheme, even for input "about:foo". 101 styles.push_back(ACMatchClassification(0, kMatch)); 102 string16 match_string = kChrome + *i; 103 if (match_string.length() > match_length) 104 styles.push_back(ACMatchClassification(match_length, kUrl)); 105 AddMatch(match_string, styles); 106 } 107 } 108 } 109 } 110 111 for (size_t i = 0; i < matches_.size(); ++i) 112 matches_[i].relevance = kRelevance + matches_.size() - (i + 1); 113 } 114 115 BuiltinProvider::~BuiltinProvider() {} 116 117 void BuiltinProvider::AddMatch(const string16& match_string, 118 const ACMatchClassifications& styles) { 119 AutocompleteMatch match(this, kRelevance, false, 120 AutocompleteMatchType::NAVSUGGEST); 121 match.fill_into_edit = match_string; 122 match.destination_url = GURL(match_string); 123 match.contents = match_string; 124 match.contents_class = styles; 125 matches_.push_back(match); 126 } 127