| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ | 5 #ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ |
| 6 #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ | 6 #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include <string> | 9 #include <string> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/logging.h" | |
| 13 #include "base/string16.h" | 12 #include "base/string16.h" |
| 14 #include "base/time.h" | |
| 15 #include "base/timer.h" | |
| 16 #include "chrome/browser/autocomplete/autocomplete_types.h" | |
| 17 #include "googleurl/src/gurl.h" | 13 #include "googleurl/src/gurl.h" |
| 18 #include "googleurl/src/url_parse.h" | 14 #include "googleurl/src/url_parse.h" |
| 19 | 15 |
| 20 // The AutocompleteController is the center of the autocomplete system. A | |
| 21 // class creates an instance of the controller, which in turn creates a set of | |
| 22 // AutocompleteProviders to serve it. The owning class can ask the controller | |
| 23 // to Start() a query; the controller in turn passes this call down to the | |
| 24 // providers, each of which keeps track of its own matches and whether it has | |
| 25 // finished processing the query. When a provider gets more matches or finishes | |
| 26 // processing, it notifies the controller, which merges the combined matches | |
| 27 // together and makes the result available to interested observers. | |
| 28 // | |
| 29 // The owner may also cancel the current query by calling Stop(), which the | |
| 30 // controller will in turn communicate to all the providers. No callbacks will | |
| 31 // happen after a request has been stopped. | |
| 32 // | |
| 33 // IMPORTANT: There is NO THREAD SAFETY built into this portion of the | |
| 34 // autocomplete system. All calls to and from the AutocompleteController should | |
| 35 // happen on the same thread. AutocompleteProviders are responsible for doing | |
| 36 // their own thread management when they need to return matches asynchronously. | |
| 37 // | |
| 38 // The AutocompleteProviders each return different kinds of matches, | |
| 39 // such as history or search matches. These matches are given | |
| 40 // "relevance" scores. Higher scores are better matches than lower | |
| 41 // scores. The relevance scores and classes providing the respective | |
| 42 // matches are as listed below. | |
| 43 // | |
| 44 // IMPORTANT CAVEAT: The tables below are NOT COMPLETE. Developers | |
| 45 // often forget to keep these tables in sync with the code when they | |
| 46 // change scoring algorithms or add new providers. For example, | |
| 47 // neither the HistoryQuickProvider (which is a provider that appears | |
| 48 // often) nor the ShortcutsProvider are listed here. For the best | |
| 49 // idea of how scoring works and what providers are affecting which | |
| 50 // queries, play with chrome://omnibox/ for a while. While the tables | |
| 51 // below may have some utility, nothing compares with first-hand | |
| 52 // investigation and experience. | |
| 53 // | |
| 54 // UNKNOWN input type: | |
| 55 // --------------------------------------------------------------------|----- | |
| 56 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 | |
| 57 // Extension App (exact match) | 1425 | |
| 58 // HistoryURL (good exact or inline autocomplete matches, some inexact)| 1410++ | |
| 59 // HistoryURL (intranet url never visited match, some inexact matches) | 1400++ | |
| 60 // Search Primary Provider (past query in history within 2 days) | 1399** | |
| 61 // Search Primary Provider (what you typed) | 1300 | |
| 62 // HistoryURL (what you typed, some inexact matches) | 1200++ | |
| 63 // Extension App (inexact match) | 1175*~ | |
| 64 // Keyword (substituting, exact match) | 1100 | |
| 65 // Search Primary Provider (past query in history older than 2 days) | 1050-- | |
| 66 // HistoryContents (any match in title of starred page) | 1000++ | |
| 67 // HistoryURL (some inexact matches) | 900++ | |
| 68 // Search Primary Provider (navigational suggestion) | 800++ | |
| 69 // HistoryContents (any match in title of nonstarred page) | 700++ | |
| 70 // Search Primary Provider (suggestion) | 600++ | |
| 71 // Built-in | 575++ | |
| 72 // HistoryContents (any match in body of starred page) | 550++ | |
| 73 // HistoryContents (any match in body of nonstarred page) | 500++ | |
| 74 // Keyword (inexact match) | 450 | |
| 75 // Search Secondary Provider (what you typed) | 250 | |
| 76 // Search Secondary Provider (past query in history) | 200-- | |
| 77 // Search Secondary Provider (navigational suggestion) | 150++ | |
| 78 // Search Secondary Provider (suggestion) | 100++ | |
| 79 // | |
| 80 // REQUESTED_URL input type: | |
| 81 // --------------------------------------------------------------------|----- | |
| 82 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 | |
| 83 // Extension App (exact match) | 1425 | |
| 84 // HistoryURL (good exact or inline autocomplete matches, some inexact)| 1410++ | |
| 85 // HistoryURL (intranet url never visited match, some inexact matches) | 1400++ | |
| 86 // Search Primary Provider (past query in history within 2 days) | 1399** | |
| 87 // HistoryURL (what you typed, some inexact matches) | 1200++ | |
| 88 // Extension App (inexact match) | 1175*~ | |
| 89 // Search Primary Provider (what you typed) | 1150 | |
| 90 // Keyword (substituting, exact match) | 1100 | |
| 91 // Search Primary Provider (past query in history older than 2 days) | 1050-- | |
| 92 // HistoryContents (any match in title of starred page) | 1000++ | |
| 93 // HistoryURL (some inexact matches) | 900++ | |
| 94 // Search Primary Provider (navigational suggestion) | 800++ | |
| 95 // HistoryContents (any match in title of nonstarred page) | 700++ | |
| 96 // Search Primary Provider (suggestion) | 600++ | |
| 97 // Built-in | 575++ | |
| 98 // HistoryContents (any match in body of starred page) | 550++ | |
| 99 // HistoryContents (any match in body of nonstarred page) | 500++ | |
| 100 // Keyword (inexact match) | 450 | |
| 101 // Search Secondary Provider (what you typed) | 250 | |
| 102 // Search Secondary Provider (past query in history) | 200-- | |
| 103 // Search Secondary Provider (navigational suggestion) | 150++ | |
| 104 // Search Secondary Provider (suggestion) | 100++ | |
| 105 // | |
| 106 // URL input type: | |
| 107 // --------------------------------------------------------------------|----- | |
| 108 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 | |
| 109 // Extension App (exact match) | 1425 | |
| 110 // HistoryURL (good exact or inline autocomplete matches, some inexact)| 1410++ | |
| 111 // HistoryURL (intranet url never visited match, some inexact matches) | 1400++ | |
| 112 // HistoryURL (what you typed, some inexact matches) | 1200++ | |
| 113 // Extension App (inexact match) | 1175*~ | |
| 114 // Keyword (substituting, exact match) | 1100 | |
| 115 // HistoryURL (some inexact matches) | 900++ | |
| 116 // Search Primary Provider (what you typed) | 850 | |
| 117 // Search Primary Provider (navigational suggestion) | 800++ | |
| 118 // Search Primary Provider (past query in history) | 750-- | |
| 119 // Keyword (inexact match) | 700 | |
| 120 // Built-in | 575++ | |
| 121 // Search Primary Provider (suggestion) | 300++ | |
| 122 // Search Secondary Provider (what you typed) | 250 | |
| 123 // Search Secondary Provider (past query in history) | 200-- | |
| 124 // Search Secondary Provider (navigational suggestion) | 150++ | |
| 125 // Search Secondary Provider (suggestion) | 100++ | |
| 126 // | |
| 127 // QUERY input type: | |
| 128 // --------------------------------------------------------------------|----- | |
| 129 // Search Primary or Secondary (past query in history within 2 days) | 1599** | |
| 130 // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 | |
| 131 // Keyword (substituting, exact match) | 1450 | |
| 132 // Extension App (exact match) | 1425 | |
| 133 // Search Primary Provider (past query in history within 2 days) | 1399** | |
| 134 // Search Primary Provider (what you typed) | 1300 | |
| 135 // Extension App (inexact match) | 1175*~ | |
| 136 // Search Primary Provider (past query in history older than 2 days) | 1050-- | |
| 137 // HistoryContents (any match in title of starred page) | 1000++ | |
| 138 // HistoryURL (inexact match) | 900++ | |
| 139 // Search Primary Provider (navigational suggestion) | 800++ | |
| 140 // HistoryContents (any match in title of nonstarred page) | 700++ | |
| 141 // Search Primary Provider (suggestion) | 600++ | |
| 142 // HistoryContents (any match in body of starred page) | 550++ | |
| 143 // HistoryContents (any match in body of nonstarred page) | 500++ | |
| 144 // Keyword (inexact match) | 450 | |
| 145 // Search Secondary Provider (what you typed) | 250 | |
| 146 // Search Secondary Provider (past query in history) | 200-- | |
| 147 // Search Secondary Provider (navigational suggestion) | 150++ | |
| 148 // Search Secondary Provider (suggestion) | 100++ | |
| 149 // | |
| 150 // FORCED_QUERY input type: | |
| 151 // --------------------------------------------------------------------|----- | |
| 152 // Extension App (exact match on title only, not url) | 1425 | |
| 153 // Search Primary Provider (past query in history within 2 days) | 1399** | |
| 154 // Search Primary Provider (what you typed) | 1300 | |
| 155 // Extension App (inexact match on title only, not url) | 1175*~ | |
| 156 // Search Primary Provider (past query in history older than 2 days) | 1050-- | |
| 157 // HistoryContents (any match in title of starred page) | 1000++ | |
| 158 // Search Primary Provider (navigational suggestion) | 800++ | |
| 159 // HistoryContents (any match in title of nonstarred page) | 700++ | |
| 160 // Search Primary Provider (suggestion) | 600++ | |
| 161 // HistoryContents (any match in body of starred page) | 550++ | |
| 162 // HistoryContents (any match in body of nonstarred page) | 500++ | |
| 163 // | |
| 164 // (A search keyword is a keyword with a replacement string; a bookmark keyword | |
| 165 // is a keyword with no replacement string, that is, a shortcut for a URL.) | |
| 166 // | |
| 167 // There are two possible providers for search suggestions. If the user has | |
| 168 // typed a keyword, then the primary provider is the keyword provider and the | |
| 169 // secondary provider is the default provider. If the user has not typed a | |
| 170 // keyword, then the primary provider corresponds to the default provider. | |
| 171 // | |
| 172 // Search providers may supply relevance values along with their results to be | |
| 173 // used in place of client-side calculated values. | |
| 174 // | |
| 175 // The value column gives the ranking returned from the various providers. | |
| 176 // ++: a series of matches with relevance from n up to (n + max_matches). | |
| 177 // --: relevance score falls off over time (discounted 50 points @ 15 minutes, | |
| 178 // 450 points @ two weeks) | |
| 179 // **: relevance score falls off over two days (discounted 99 points after two | |
| 180 // days). | |
| 181 // *~: Partial matches get a score on a sliding scale from about 575-1125 based | |
| 182 // on how many times the URL for the Extension App has been typed and how | |
| 183 // many of the letters match. | |
| 184 | |
| 185 struct AutocompleteMatch; | |
| 186 class AutocompleteProvider; | |
| 187 | |
| 188 // AutocompleteInput ---------------------------------------------------------- | |
| 189 | |
| 190 // The user input for an autocomplete query. Allows copying. | 16 // The user input for an autocomplete query. Allows copying. |
| 191 class AutocompleteInput { | 17 class AutocompleteInput { |
| 192 public: | 18 public: |
| 193 // Note that the type below may be misleading. For example, "http:/" alone | 19 // Note that the type below may be misleading. For example, "http:/" alone |
| 194 // cannot be opened as a URL, so it is marked as a QUERY; yet the user | 20 // cannot be opened as a URL, so it is marked as a QUERY; yet the user |
| 195 // probably intends to type more and have it eventually become a URL, so we | 21 // probably intends to type more and have it eventually become a URL, so we |
| 196 // need to make sure we still run it through inline autocomplete. | 22 // need to make sure we still run it through inline autocomplete. |
| 197 enum Type { | 23 enum Type { |
| 198 INVALID, // Empty input | 24 INVALID, // Empty input |
| 199 UNKNOWN, // Valid input whose type cannot be determined | 25 UNKNOWN, // Valid input whose type cannot be determined |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 Type type_; | 151 Type type_; |
| 326 url_parse::Parsed parts_; | 152 url_parse::Parsed parts_; |
| 327 string16 scheme_; | 153 string16 scheme_; |
| 328 GURL canonicalized_url_; | 154 GURL canonicalized_url_; |
| 329 bool prevent_inline_autocomplete_; | 155 bool prevent_inline_autocomplete_; |
| 330 bool prefer_keyword_; | 156 bool prefer_keyword_; |
| 331 bool allow_exact_keyword_match_; | 157 bool allow_exact_keyword_match_; |
| 332 MatchesRequested matches_requested_; | 158 MatchesRequested matches_requested_; |
| 333 }; | 159 }; |
| 334 | 160 |
| 335 // AutocompleteResult --------------------------------------------------------- | |
| 336 | |
| 337 // All matches from all providers for a particular query. This also tracks | |
| 338 // what the default match should be if the user doesn't manually select another | |
| 339 // match. | |
| 340 class AutocompleteResult { | |
| 341 public: | |
| 342 typedef ACMatches::const_iterator const_iterator; | |
| 343 typedef ACMatches::iterator iterator; | |
| 344 | |
| 345 // The "Selection" struct is the information we need to select the same match | |
| 346 // in one result set that was selected in another. | |
| 347 struct Selection { | |
| 348 Selection() | |
| 349 : provider_affinity(NULL), | |
| 350 is_history_what_you_typed_match(false) { | |
| 351 } | |
| 352 | |
| 353 // Clear the selection entirely. | |
| 354 void Clear(); | |
| 355 | |
| 356 // True when the selection is empty. | |
| 357 bool empty() const { | |
| 358 return destination_url.is_empty() && !provider_affinity && | |
| 359 !is_history_what_you_typed_match; | |
| 360 } | |
| 361 | |
| 362 // The desired destination URL. | |
| 363 GURL destination_url; | |
| 364 | |
| 365 // The desired provider. If we can't find a match with the specified | |
| 366 // |destination_url|, we'll use the best match from this provider. | |
| 367 const AutocompleteProvider* provider_affinity; | |
| 368 | |
| 369 // True when this is the HistoryURLProvider's "what you typed" match. This | |
| 370 // can't be tracked using |destination_url| because its URL changes on every | |
| 371 // keystroke, so if this is set, we'll preserve the selection by simply | |
| 372 // choosing the new "what you typed" entry and ignoring |destination_url|. | |
| 373 bool is_history_what_you_typed_match; | |
| 374 }; | |
| 375 | |
| 376 // Max number of matches we'll show from the various providers. | |
| 377 static const size_t kMaxMatches; | |
| 378 | |
| 379 // The lowest score a match can have and still potentially become the default | |
| 380 // match for the result set. | |
| 381 static const int kLowestDefaultScore; | |
| 382 | |
| 383 AutocompleteResult(); | |
| 384 ~AutocompleteResult(); | |
| 385 | |
| 386 // operator=() by another name. | |
| 387 void CopyFrom(const AutocompleteResult& rhs); | |
| 388 | |
| 389 // Copies matches from |old_matches| to provide a consistant result set. See | |
| 390 // comments in code for specifics. | |
| 391 void CopyOldMatches(const AutocompleteInput& input, | |
| 392 const AutocompleteResult& old_matches); | |
| 393 | |
| 394 // Adds a single match. The match is inserted at the appropriate position | |
| 395 // based on relevancy and display order. This is ONLY for use after | |
| 396 // SortAndCull() has been invoked, and preserves default_match_. | |
| 397 void AddMatch(const AutocompleteMatch& match); | |
| 398 | |
| 399 // Adds a new set of matches to the result set. Does not re-sort. | |
| 400 void AppendMatches(const ACMatches& matches); | |
| 401 | |
| 402 // Removes duplicates, puts the list in sorted order and culls to leave only | |
| 403 // the best kMaxMatches matches. Sets the default match to the best match | |
| 404 // and updates the alternate nav URL. | |
| 405 void SortAndCull(const AutocompleteInput& input); | |
| 406 | |
| 407 // Returns true if at least one match was copied from the last result. | |
| 408 bool HasCopiedMatches() const; | |
| 409 | |
| 410 // Vector-style accessors/operators. | |
| 411 size_t size() const; | |
| 412 bool empty() const; | |
| 413 const_iterator begin() const; | |
| 414 iterator begin(); | |
| 415 const_iterator end() const; | |
| 416 iterator end(); | |
| 417 | |
| 418 // Returns the match at the given index. | |
| 419 const AutocompleteMatch& match_at(size_t index) const; | |
| 420 AutocompleteMatch* match_at(size_t index); | |
| 421 | |
| 422 // Get the default match for the query (not necessarily the first). Returns | |
| 423 // end() if there is no default match. | |
| 424 const_iterator default_match() const { return default_match_; } | |
| 425 | |
| 426 const GURL& alternate_nav_url() const { return alternate_nav_url_; } | |
| 427 | |
| 428 // Clears the matches for this result set. | |
| 429 void Reset(); | |
| 430 | |
| 431 void Swap(AutocompleteResult* other); | |
| 432 | |
| 433 #ifndef NDEBUG | |
| 434 // Does a data integrity check on this result. | |
| 435 void Validate() const; | |
| 436 #endif | |
| 437 | |
| 438 private: | |
| 439 typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches; | |
| 440 | |
| 441 #if defined(OS_ANDROID) | |
| 442 // iterator::difference_type is not defined in the STL that we compile with on | |
| 443 // Android. | |
| 444 typedef int matches_difference_type; | |
| 445 #else | |
| 446 typedef ACMatches::iterator::difference_type matches_difference_type; | |
| 447 #endif | |
| 448 | |
| 449 // Populates |provider_to_matches| from |matches_|. | |
| 450 void BuildProviderToMatches(ProviderToMatches* provider_to_matches) const; | |
| 451 | |
| 452 // Returns true if |matches| contains a match with the same destination as | |
| 453 // |match|. | |
| 454 static bool HasMatchByDestination(const AutocompleteMatch& match, | |
| 455 const ACMatches& matches); | |
| 456 | |
| 457 // Copies matches into this result. |old_matches| gives the matches from the | |
| 458 // last result, and |new_matches| the results from this result. | |
| 459 void MergeMatchesByProvider(const ACMatches& old_matches, | |
| 460 const ACMatches& new_matches); | |
| 461 | |
| 462 ACMatches matches_; | |
| 463 | |
| 464 const_iterator default_match_; | |
| 465 | |
| 466 // The "alternate navigation URL", if any, for this result set. This is a URL | |
| 467 // to try offering as a navigational option in case the user navigated to the | |
| 468 // URL of the default match but intended something else. For example, if the | |
| 469 // user's local intranet contains site "foo", and the user types "foo", we | |
| 470 // default to searching for "foo" when the user may have meant to navigate | |
| 471 // there. In cases like this, the default match will point to the "search for | |
| 472 // 'foo'" result, and this will contain "http://foo/". | |
| 473 GURL alternate_nav_url_; | |
| 474 | |
| 475 DISALLOW_COPY_AND_ASSIGN(AutocompleteResult); | |
| 476 }; | |
| 477 | |
| 478 #endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ | 161 #endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ |
| OLD | NEW |