summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete/history_quick_provider.cc
diff options
context:
space:
mode:
authormrossetti@chromium.org <mrossetti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-11 22:06:00 +0000
committermrossetti@chromium.org <mrossetti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-11 22:06:00 +0000
commitf2bfc1ce3ff150af8e375151a106f8cfc5b6fb08 (patch)
tree7f941e8fa002ce991963663e5a874fc479257d93 /chrome/browser/autocomplete/history_quick_provider.cc
parentcc378a1cc341ecfb60aeaba995ea0b442c9bc83e (diff)
downloadchromium_src-f2bfc1ce3ff150af8e375151a106f8cfc5b6fb08.zip
chromium_src-f2bfc1ce3ff150af8e375151a106f8cfc5b6fb08.tar.gz
chromium_src-f2bfc1ce3ff150af8e375151a106f8cfc5b6fb08.tar.bz2
Final phase of the URL History Quick autocomplete provider integration. This phase hooks up the InMemoryURLIndex to the HistoryQuickProvider which is itself made active during the autocomplete process. A small amount of refactoring was done to liberate some common functionality from the history_url_provider.
BUG=None TEST=None Review URL: http://codereview.chromium.org/3375002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62193 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete/history_quick_provider.cc')
-rw-r--r--chrome/browser/autocomplete/history_quick_provider.cc188
1 files changed, 187 insertions, 1 deletions
diff --git a/chrome/browser/autocomplete/history_quick_provider.cc b/chrome/browser/autocomplete/history_quick_provider.cc
index 0d4fdda..776c343 100644
--- a/chrome/browser/autocomplete/history_quick_provider.cc
+++ b/chrome/browser/autocomplete/history_quick_provider.cc
@@ -4,7 +4,193 @@
#include "chrome/browser/autocomplete/history_quick_provider.h"
+#include "base/basictypes.h"
+#include "base/histogram.h"
+#include "base/i18n/word_iterator.h"
+#include "base/string_util.h"
+#include "base/logging.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/history/history.h"
+#include "chrome/browser/prefs/pref_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/history/in_memory_url_index.h"
+#include "chrome/browser/net/url_fixer_upper.h"
+#include "chrome/browser/plugin_service.h"
+#include "chrome/common/notification_source.h"
+#include "chrome/common/notification_type.h"
+#include "chrome/common/pref_names.h"
+#include "chrome/common/url_constants.h"
+#include "googleurl/src/url_util.h"
+#include "net/base/escape.h"
+#include "net/base/net_util.h"
+
+using history::InMemoryURLIndex;
+using history::ScoredHistoryMatch;
+using history::ScoredHistoryMatches;
+
+HistoryQuickProvider::HistoryQuickProvider(ACProviderListener* listener,
+ Profile* profile)
+ : HistoryProvider(listener, profile, "HistoryQuickProvider"),
+ trim_http_(false),
+ languages_(profile_->GetPrefs()->GetString(prefs::kAcceptLanguages)) {}
+
+HistoryQuickProvider::~HistoryQuickProvider() {}
+
void HistoryQuickProvider::Start(const AutocompleteInput& input,
bool minimal_changes) {
- // TODO(mrossetti): Implement.
+ matches_.clear();
+
+ if ((input.type() == AutocompleteInput::INVALID) ||
+ (input.type() == AutocompleteInput::FORCED_QUERY))
+ return;
+
+ autocomplete_input_ = input;
+ trim_http_ = !HasHTTPScheme(input.text());
+
+ // Do some fixup on the user input before matching against it, so we provide
+ // good results for local file paths, input with spaces, etc.
+ // NOTE: This purposefully doesn't take input.desired_tld() into account; if
+ // it did, then holding "ctrl" would change all the results from the
+ // HistoryQuickProvider provider, not just the What You Typed Result.
+ const std::wstring fixed_text(FixupUserInput(input));
+ if (fixed_text.empty()) {
+ // Conceivably fixup could result in an empty string (although I don't
+ // have cases where this happens offhand). We can't do anything with
+ // empty input, so just bail; otherwise we'd crash later.
+ return;
+ }
+ autocomplete_input_.set_text(fixed_text);
+
+ // TODO(pkasting): We should just block here until this loads. Any time
+ // someone unloads the history backend, we'll get inconsistent inline
+ // autocomplete behavior here.
+ if (GetIndex()) {
+ DoAutocomplete();
+ UpdateStarredStateOfMatches();
+ }
+}
+
+void HistoryQuickProvider::DoAutocomplete() {
+ // Get the matching URLs from the DB.
+ string16 term_string(WideToUTF16(autocomplete_input_.text()));
+ term_string = UnescapeURLComponent(term_string,
+ UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
+ history::InMemoryURLIndex::String16Vector terms(
+ HistoryQuickProvider::WordVectorFromString16(term_string));
+ ScoredHistoryMatches matches = GetIndex()->HistoryItemsForTerms(terms);
+
+ size_t match_num = matches.size() - 1;
+ for (ScoredHistoryMatches::const_iterator match_iter = matches.begin();
+ match_iter != matches.end(); ++match_iter, --match_num) {
+ const ScoredHistoryMatch& history_match(*match_iter);
+ AutocompleteMatch ac_match =
+ QuickMatchToACMatch(history_match, NORMAL, match_num);
+ matches_.push_back(ac_match);
+ }
+}
+
+AutocompleteMatch HistoryQuickProvider::QuickMatchToACMatch(
+ const ScoredHistoryMatch& history_match,
+ MatchType match_type,
+ size_t match_number) {
+ const history::URLRow& info = history_match.url_info;
+ int score = CalculateRelevance(history_match.raw_score,
+ autocomplete_input_.type(),
+ match_type, match_number);
+ AutocompleteMatch match(this, score, !!info.visit_count(),
+ AutocompleteMatch::HISTORY_URL);
+ match.destination_url = info.url();
+ DCHECK(match.destination_url.is_valid());
+ size_t inline_autocomplete_offset =
+ history_match.input_location + autocomplete_input_.text().length();
+ const net::FormatUrlTypes format_types = net::kFormatUrlOmitAll &
+ ~((trim_http_ && !history_match.match_in_scheme) ?
+ 0 : net::kFormatUrlOmitHTTP);
+ std::string languages =
+ match_type == WHAT_YOU_TYPED ? std::string() : languages_;
+ match.fill_into_edit =
+ AutocompleteInput::FormattedStringWithEquivalentMeaning(info.url(),
+ UTF16ToWide(net::FormatUrl(info.url(), languages, format_types,
+ UnescapeRule::SPACES, NULL, NULL,
+ &inline_autocomplete_offset)));
+ if (!autocomplete_input_.prevent_inline_autocomplete())
+ match.inline_autocomplete_offset = inline_autocomplete_offset;
+ DCHECK((match.inline_autocomplete_offset == std::wstring::npos) ||
+ (match.inline_autocomplete_offset <= match.fill_into_edit.length()));
+
+ size_t match_start = history_match.input_location;
+ match.contents =
+ UTF16ToWide(net::FormatUrl(info.url(), languages, format_types,
+ UnescapeRule::SPACES, NULL, NULL,
+ &match_start));
+ if ((match_start != std::wstring::npos) &&
+ (inline_autocomplete_offset != std::wstring::npos) &&
+ (inline_autocomplete_offset != match_start)) {
+ DCHECK(inline_autocomplete_offset > match_start);
+ AutocompleteMatch::ClassifyLocationInString(match_start,
+ inline_autocomplete_offset - match_start, match.contents.length(),
+ ACMatchClassification::URL, &match.contents_class);
+ } else {
+ AutocompleteMatch::ClassifyLocationInString(std::wstring::npos, 0,
+ match.contents.length(), ACMatchClassification::URL,
+ &match.contents_class);
+ }
+ match.description = UTF16ToWide(info.title());
+ AutocompleteMatch::ClassifyMatchInString(autocomplete_input_.text(),
+ UTF16ToWide(info.title()),
+ ACMatchClassification::NONE,
+ &match.description_class);
+
+ return match;
}
+
+history::InMemoryURLIndex* HistoryQuickProvider::GetIndex() {
+ if (index_for_testing_.get())
+ return index_for_testing_.get();
+
+ HistoryService* const history_service =
+ profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
+ if (!history_service)
+ return NULL;
+
+ return history_service->InMemoryIndex();
+}
+
+void HistoryQuickProvider::SetIndexForTesting(
+ history::InMemoryURLIndex* index) {
+ DCHECK(index);
+ index_for_testing_.reset(index);
+}
+
+// Utility Functions
+
+history::InMemoryURLIndex::String16Vector
+ HistoryQuickProvider::WordVectorFromString16(const string16& uni_string) {
+ history::InMemoryURLIndex::String16Vector words;
+ WordIterator iter(&uni_string, WordIterator::BREAK_WORD);
+ if (iter.Init()) {
+ while (iter.Advance()) {
+ if (iter.IsWord())
+ words.push_back(iter.GetWord());
+ }
+ }
+ return words;
+}
+
+// static
+int HistoryQuickProvider::CalculateRelevance(int raw_score,
+ AutocompleteInput::Type input_type,
+ MatchType match_type,
+ size_t match_number) {
+ switch (match_type) {
+ case INLINE_AUTOCOMPLETE:
+ return 1400;
+
+ case WHAT_YOU_TYPED:
+ return 1200;
+
+ default:
+ return 900 + static_cast<int>(match_number);
+ }
+}
+