| // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ |
| #define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ |
| #pragma once |
| |
| #include <map> |
| #include <string> |
| #include <vector> |
| |
| #include "base/logging.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/string16.h" |
| #include "base/timer.h" |
| #include "googleurl/src/gurl.h" |
| #include "googleurl/src/url_parse.h" |
| |
| // The AutocompleteController is the center of the autocomplete system. A |
| // class creates an instance of the controller, which in turn creates a set of |
| // AutocompleteProviders to serve it. The owning class can ask the controller |
| // to Start() a query; the controller in turn passes this call down to the |
| // providers, each of which keeps track of its own matches and whether it has |
| // finished processing the query. When a provider gets more matches or finishes |
| // processing, it notifies the controller, which merges the combined matches |
| // together and makes the result available to interested observers. |
| // |
| // The owner may also cancel the current query by calling Stop(), which the |
| // controller will in turn communicate to all the providers. No callbacks will |
| // happen after a request has been stopped. |
| // |
| // IMPORTANT: There is NO THREAD SAFETY built into this portion of the |
| // autocomplete system. All calls to and from the AutocompleteController should |
| // happen on the same thread. AutocompleteProviders are responsible for doing |
| // their own thread management when they need to return matches asynchronously. |
| // |
| // The AutocompleteProviders each return different kinds of matches, such as |
| // history or search matches. These matches are given "relevance" scores. |
| // Higher scores are better matches than lower scores. The relevance scores and |
| // classes providing the respective matches are as follows: |
| // |
| // UNKNOWN input type: |
| // --------------------------------------------------------------------|----- |
| // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 |
| // Extension App (exact match) | 1425 |
| // HistoryURL (exact or inline autocomplete match) | 1400 |
| // Search Primary Provider (past query in history within 2 days) | 1399** |
| // Search Primary Provider (what you typed) | 1300 |
| // HistoryURL (what you typed) | 1200 |
| // Extension App (inexact match) | 1175*~ |
| // Keyword (substituting, exact match) | 1100 |
| // Search Primary Provider (past query in history older than 2 days) | 1050-- |
| // HistoryContents (any match in title of starred page) | 1000++ |
| // HistoryURL (inexact match) | 900++ |
| // Search Primary Provider (navigational suggestion) | 800++ |
| // HistoryContents (any match in title of nonstarred page) | 700++ |
| // Search Primary Provider (suggestion) | 600++ |
| // Built-in | 575++ |
| // HistoryContents (any match in body of starred page) | 550++ |
| // HistoryContents (any match in body of nonstarred page) | 500++ |
| // Keyword (inexact match) | 450 |
| // Search Secondary Provider (what you typed) | 250 |
| // Search Secondary Provider (past query in history) | 200-- |
| // Search Secondary Provider (navigational suggestion) | 150++ |
| // Search Secondary Provider (suggestion) | 100++ |
| // |
| // REQUESTED_URL input type: |
| // --------------------------------------------------------------------|----- |
| // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 |
| // Extension App (exact match) | 1425 |
| // HistoryURL (exact or inline autocomplete match) | 1400 |
| // Search Primary Provider (past query in history within 2 days) | 1399** |
| // HistoryURL (what you typed) | 1200 |
| // Extension App (inexact match) | 1175*~ |
| // Search Primary Provider (what you typed) | 1150 |
| // Keyword (substituting, exact match) | 1100 |
| // Search Primary Provider (past query in history older than 2 days) | 1050-- |
| // HistoryContents (any match in title of starred page) | 1000++ |
| // HistoryURL (inexact match) | 900++ |
| // Search Primary Provider (navigational suggestion) | 800++ |
| // HistoryContents (any match in title of nonstarred page) | 700++ |
| // Search Primary Provider (suggestion) | 600++ |
| // Built-in | 575++ |
| // HistoryContents (any match in body of starred page) | 550++ |
| // HistoryContents (any match in body of nonstarred page) | 500++ |
| // Keyword (inexact match) | 450 |
| // Search Secondary Provider (what you typed) | 250 |
| // Search Secondary Provider (past query in history) | 200-- |
| // Search Secondary Provider (navigational suggestion) | 150++ |
| // Search Secondary Provider (suggestion) | 100++ |
| // |
| // URL input type: |
| // --------------------------------------------------------------------|----- |
| // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 |
| // Extension App (exact match) | 1425 |
| // HistoryURL (exact or inline autocomplete match) | 1400 |
| // HistoryURL (what you typed) | 1200 |
| // Extension App (inexact match) | 1175*~ |
| // Keyword (substituting, exact match) | 1100 |
| // HistoryURL (inexact match) | 900++ |
| // Search Primary Provider (what you typed) | 850 |
| // Search Primary Provider (navigational suggestion) | 800++ |
| // Search Primary Provider (past query in history) | 750-- |
| // Keyword (inexact match) | 700 |
| // Built-in | 575++ |
| // Search Primary Provider (suggestion) | 300++ |
| // Search Secondary Provider (what you typed) | 250 |
| // Search Secondary Provider (past query in history) | 200-- |
| // Search Secondary Provider (navigational suggestion) | 150++ |
| // Search Secondary Provider (suggestion) | 100++ |
| // |
| // QUERY input type: |
| // --------------------------------------------------------------------|----- |
| // Keyword (non-substituting or in keyword UI mode, exact match) | 1500 |
| // Keyword (substituting, exact match) | 1450 |
| // Extension App (exact match) | 1425 |
| // HistoryURL (exact or inline autocomplete match) | 1400 |
| // Search Primary Provider (past query in history within 2 days) | 1399** |
| // Search Primary Provider (what you typed) | 1300 |
| // Extension App (inexact match) | 1175*~ |
| // Search Primary Provider (past query in history older than 2 days) | 1050-- |
| // HistoryContents (any match in title of starred page) | 1000++ |
| // HistoryURL (inexact match) | 900++ |
| // Search Primary Provider (navigational suggestion) | 800++ |
| // HistoryContents (any match in title of nonstarred page) | 700++ |
| // Search Primary Provider (suggestion) | 600++ |
| // HistoryContents (any match in body of starred page) | 550++ |
| // HistoryContents (any match in body of nonstarred page) | 500++ |
| // Keyword (inexact match) | 450 |
| // Search Secondary Provider (what you typed) | 250 |
| // Search Secondary Provider (past query in history) | 200-- |
| // Search Secondary Provider (navigational suggestion) | 150++ |
| // Search Secondary Provider (suggestion) | 100++ |
| // |
| // FORCED_QUERY input type: |
| // --------------------------------------------------------------------|----- |
| // Extension App (exact match on title only, not url) | 1425 |
| // Search Primary Provider (past query in history within 2 days) | 1399** |
| // Search Primary Provider (what you typed) | 1300 |
| // Extension App (inexact match on title only, not url) | 1175*~ |
| // Search Primary Provider (past query in history older than 2 days) | 1050-- |
| // HistoryContents (any match in title of starred page) | 1000++ |
| // Search Primary Provider (navigational suggestion) | 800++ |
| // HistoryContents (any match in title of nonstarred page) | 700++ |
| // Search Primary Provider (suggestion) | 600++ |
| // HistoryContents (any match in body of starred page) | 550++ |
| // HistoryContents (any match in body of nonstarred page) | 500++ |
| // |
| // (A search keyword is a keyword with a replacement string; a bookmark keyword |
| // is a keyword with no replacement string, that is, a shortcut for a URL.) |
| // |
| // There are two possible providers for search suggestions. If the user has |
| // typed a keyword, then the primary provider is the keyword provider and the |
| // secondary provider is the default provider. If the user has not typed a |
| // keyword, then the primary provider corresponds to the default provider. |
| // |
| // The value column gives the ranking returned from the various providers. |
| // ++: a series of matches with relevance from n up to (n + max_matches). |
| // --: relevance score falls off over time (discounted 50 points @ 15 minutes, |
| // 450 points @ two weeks) |
| // **: relevance score falls off over two days (discounted 99 points after two |
| // days). |
| // *~: Partial matches get a score on a sliding scale from about 575-1125 based |
| // on how many times the URL for the Extension App has been typed and how |
| // many of the letters match. |
| |
| class AutocompleteController; |
| class AutocompleteControllerDelegate; |
| class AutocompleteInput; |
| struct AutocompleteMatch; |
| class AutocompleteProvider; |
| class AutocompleteResult; |
| class HistoryContentsProvider; |
| class Profile; |
| class SearchProvider; |
| class TemplateURL; |
| |
| typedef std::vector<AutocompleteMatch> ACMatches; |
| typedef std::vector<AutocompleteProvider*> ACProviders; |
| |
| // AutocompleteInput ---------------------------------------------------------- |
| |
| // The user input for an autocomplete query. Allows copying. |
| class AutocompleteInput { |
| public: |
| // Note that the type below may be misleading. For example, "http:/" alone |
| // cannot be opened as a URL, so it is marked as a QUERY; yet the user |
| // probably intends to type more and have it eventually become a URL, so we |
| // need to make sure we still run it through inline autocomplete. |
| enum Type { |
| INVALID, // Empty input |
| UNKNOWN, // Valid input whose type cannot be determined |
| REQUESTED_URL, // Input autodetected as UNKNOWN, which the user wants to |
| // treat as an URL by specifying a desired_tld |
| URL, // Input autodetected as a URL |
| QUERY, // Input autodetected as a query |
| FORCED_QUERY, // Input forced to be a query by an initial '?' |
| }; |
| |
| // Enumeration of the possible match query types. Callers who only need some |
| // of the matches for a particular input can get answers more quickly by |
| // specifying that upfront. |
| enum MatchesRequested { |
| // Only the best match in the whole result set matters. Providers should at |
| // most return synchronously-available matches, and if possible do even less |
| // work, so that it's safe to ask for these repeatedly in the course of one |
| // higher-level "synchronous" query. |
| BEST_MATCH, |
| |
| // Only synchronous matches should be returned. |
| SYNCHRONOUS_MATCHES, |
| |
| // All matches should be fetched. |
| ALL_MATCHES, |
| }; |
| |
| AutocompleteInput(); |
| AutocompleteInput(const string16& text, |
| const string16& desired_tld, |
| bool prevent_inline_autocomplete, |
| bool prefer_keyword, |
| bool allow_exact_keyword_match, |
| MatchesRequested matches_requested); |
| ~AutocompleteInput(); |
| |
| // If type is |FORCED_QUERY| and |text| starts with '?', it is removed. |
| static void RemoveForcedQueryStringIfNecessary(Type type, string16* text); |
| |
| // Converts |type| to a string representation. Used in logging. |
| static std::string TypeToString(Type type); |
| |
| // Parses |text| and returns the type of input this will be interpreted as. |
| // The components of the input are stored in the output parameter |parts|, if |
| // it is non-NULL. The scheme is stored in |scheme| if it is non-NULL. The |
| // canonicalized URL is stored in |canonicalized_url|; however, this URL is |
| // not guaranteed to be valid, especially if the parsed type is, e.g., QUERY. |
| static Type Parse(const string16& text, |
| const string16& desired_tld, |
| url_parse::Parsed* parts, |
| string16* scheme, |
| GURL* canonicalized_url); |
| |
| // Parses |text| and fill |scheme| and |host| by the positions of them. |
| // The results are almost as same as the result of Parse(), but if the scheme |
| // is view-source, this function returns the positions of scheme and host |
| // in the URL qualified by "view-source:" prefix. |
| static void ParseForEmphasizeComponents(const string16& text, |
| const string16& desired_tld, |
| url_parse::Component* scheme, |
| url_parse::Component* host); |
| |
| // Code that wants to format URLs with a format flag including |
| // net::kFormatUrlOmitTrailingSlashOnBareHostname risk changing the meaning if |
| // the result is then parsed as AutocompleteInput. Such code can call this |
| // function with the URL and its formatted string, and it will return a |
| // formatted string with the same meaning as the original URL (i.e. it will |
| // re-append a slash if necessary). |
| static string16 FormattedStringWithEquivalentMeaning( |
| const GURL& url, |
| const string16& formatted_url); |
| |
| // User-provided text to be completed. |
| const string16& text() const { return text_; } |
| |
| // Use of this setter is risky, since no other internal state is updated |
| // besides |text_|. Only callers who know that they're not changing the |
| // type/scheme/etc. should use this. |
| void set_text(const string16& text) { text_ = text; } |
| |
| // The text supplied to the constructor. This differs from |text| if the text |
| // supplied to the constructor had leading or trailing white space. |
| const string16& original_text() const { return original_text_; } |
| |
| // User's desired TLD, if one is not already present in the text to |
| // autocomplete. When this is non-empty, it also implies that "www." should |
| // be prepended to the domain where possible. This should not have a leading |
| // '.' (use "com" instead of ".com"). |
| const string16& desired_tld() const { return desired_tld_; } |
| |
| // The type of input supplied. |
| Type type() const { return type_; } |
| |
| // Returns parsed URL components. |
| const url_parse::Parsed& parts() const { return parts_; } |
| |
| // The scheme parsed from the provided text; only meaningful when type_ is |
| // URL. |
| const string16& scheme() const { return scheme_; } |
| |
| // The input as an URL to navigate to, if possible. |
| const GURL& canonicalized_url() const { return canonicalized_url_; } |
| |
| // Returns whether inline autocompletion should be prevented. |
| bool prevent_inline_autocomplete() const { |
| return prevent_inline_autocomplete_; |
| } |
| |
| // Returns the value of |prevent_inline_autocomplete| supplied to the |
| // constructor. This differs from the value returned by |
| // |prevent_inline_autocomplete()| if the input contained trailing whitespace. |
| bool initial_prevent_inline_autocomplete() const { |
| return initial_prevent_inline_autocomplete_; |
| } |
| |
| // Returns whether, given an input string consisting solely of a substituting |
| // keyword, we should score it like a non-substituting keyword. |
| bool prefer_keyword() const { return prefer_keyword_; } |
| |
| // Returns whether this input is allowed to be treated as an exact |
| // keyword match. If not, the default result is guaranteed not to be a |
| // keyword search, even if the input is "<keyword> <search string>". |
| bool allow_exact_keyword_match() const { return allow_exact_keyword_match_; } |
| |
| // See description of enum for details. |
| MatchesRequested matches_requested() const { return matches_requested_; } |
| |
| // operator==() by another name. |
| bool Equals(const AutocompleteInput& other) const; |
| |
| // Resets all internal variables to the null-constructed state. |
| void Clear(); |
| |
| private: |
| string16 text_; |
| string16 original_text_; |
| string16 desired_tld_; |
| Type type_; |
| url_parse::Parsed parts_; |
| string16 scheme_; |
| GURL canonicalized_url_; |
| bool initial_prevent_inline_autocomplete_; |
| bool prevent_inline_autocomplete_; |
| bool prefer_keyword_; |
| bool allow_exact_keyword_match_; |
| MatchesRequested matches_requested_; |
| }; |
| |
| // AutocompleteProvider ------------------------------------------------------- |
| |
| // A single result provider for the autocomplete system. Given user input, the |
| // provider decides what (if any) matches to return, their relevance, and their |
| // classifications. |
| class AutocompleteProvider |
| : public base::RefCountedThreadSafe<AutocompleteProvider> { |
| public: |
| class ACProviderListener { |
| public: |
| // Called by a provider as a notification that something has changed. |
| // |updated_matches| should be true iff the matches have changed in some |
| // way (they may not have changed if, for example, the provider did an |
| // asynchronous query to get more matches, came up with none, and is now |
| // giving up). |
| // |
| // NOTE: Providers MUST only call this method while processing asynchronous |
| // queries. Do not call this for a synchronous query. |
| // |
| // NOTE: There's no parameter to tell the listener _which_ provider is |
| // calling it. Because the AutocompleteController (the typical listener) |
| // doesn't cache the providers' individual matches locally, it has to get |
| // them all again when this is called anyway, so such a parameter wouldn't |
| // actually be useful. |
| virtual void OnProviderUpdate(bool updated_matches) = 0; |
| |
| protected: |
| virtual ~ACProviderListener(); |
| }; |
| |
| AutocompleteProvider(ACProviderListener* listener, |
| Profile* profile, |
| const char* name); |
| |
| // Invoked when the profile changes. |
| // NOTE: Do not access any previous Profile* at this point as it may have |
| // already been deleted. |
| void SetProfile(Profile* profile); |
| |
| // Called to start an autocomplete query. The provider is responsible for |
| // tracking its matches for this query and whether it is done processing the |
| // query. When new matches are available or the provider finishes, it |
| // calls the controller's OnProviderUpdate() method. The controller can then |
| // get the new matches using the provider's accessors. |
| // Exception: Matches available immediately after starting the query (that |
| // is, synchronously) do not cause any notifications to be sent. The |
| // controller is expected to check for these without prompting (since |
| // otherwise, starting each provider running would result in a flurry of |
| // notifications). |
| // |
| // Once Stop() has been called, no more notifications should be sent. |
| // |
| // |minimal_changes| is an optimization that lets the provider do less work |
| // when the |input|'s text hasn't changed. See the body of |
| // AutocompletePopupModel::StartAutocomplete(). |
| virtual void Start(const AutocompleteInput& input, |
| bool minimal_changes) = 0; |
| |
| // Called when a provider must not make any more callbacks for the current |
| // query. This will be called regardless of whether the provider is already |
| // done. |
| virtual void Stop(); |
| |
| // Returns the set of matches for the current query. |
| const ACMatches& matches() const { return matches_; } |
| |
| // Returns whether the provider is done processing the query. |
| bool done() const { return done_; } |
| |
| // Returns the name of this provider. |
| const char* name() const { return name_; } |
| |
| // Called to delete a match and the backing data that produced it. This |
| // match should not appear again in this or future queries. This can only be |
| // called for matches the provider marks as deletable. This should only be |
| // called when no query is running. |
| // NOTE: Remember to call OnProviderUpdate() if matches_ is updated. |
| virtual void DeleteMatch(const AutocompleteMatch& match); |
| |
| // A suggested upper bound for how many matches a provider should return. |
| // TODO(pkasting): http://b/1111299 , http://b/933133 This should go away once |
| // we have good relevance heuristics; the controller should handle all |
| // culling. |
| static const size_t kMaxMatches; |
| |
| protected: |
| friend class base::RefCountedThreadSafe<AutocompleteProvider>; |
| |
| virtual ~AutocompleteProvider(); |
| |
| // Returns whether |input| begins "http:" or "view-source:http:". |
| static bool HasHTTPScheme(const string16& input); |
| |
| // Updates the starred state of each of the matches in matches_ from the |
| // profile's bookmark bar model. |
| void UpdateStarredStateOfMatches(); |
| |
| // A convenience function to call net::FormatUrl() with the current set of |
| // "Accept Languages" when check_accept_lang is true. Otherwise, it's called |
| // with an empty list. |
| string16 StringForURLDisplay(const GURL& url, |
| bool check_accept_lang, |
| bool trim_http) const; |
| |
| // The profile associated with the AutocompleteProvider. Reference is not |
| // owned by us. |
| Profile* profile_; |
| |
| ACProviderListener* listener_; |
| ACMatches matches_; |
| bool done_; |
| |
| // The name of this provider. Used for logging. |
| const char* name_; |
| |
| private: |
| DISALLOW_COPY_AND_ASSIGN(AutocompleteProvider); |
| }; |
| |
| typedef AutocompleteProvider::ACProviderListener ACProviderListener; |
| |
| // AutocompleteResult --------------------------------------------------------- |
| |
| // All matches from all providers for a particular query. This also tracks |
| // what the default match should be if the user doesn't manually select another |
| // match. |
| class AutocompleteResult { |
| public: |
| typedef ACMatches::const_iterator const_iterator; |
| typedef ACMatches::iterator iterator; |
| |
| // The "Selection" struct is the information we need to select the same match |
| // in one result set that was selected in another. |
| struct Selection { |
| Selection() |
| : provider_affinity(NULL), |
| is_history_what_you_typed_match(false) { |
| } |
| |
| // Clear the selection entirely. |
| void Clear(); |
| |
| // True when the selection is empty. |
| bool empty() const { |
| return destination_url.is_empty() && !provider_affinity && |
| !is_history_what_you_typed_match; |
| } |
| |
| // The desired destination URL. |
| GURL destination_url; |
| |
| // The desired provider. If we can't find a match with the specified |
| // |destination_url|, we'll use the best match from this provider. |
| const AutocompleteProvider* provider_affinity; |
| |
| // True when this is the HistoryURLProvider's "what you typed" match. This |
| // can't be tracked using |destination_url| because its URL changes on every |
| // keystroke, so if this is set, we'll preserve the selection by simply |
| // choosing the new "what you typed" entry and ignoring |destination_url|. |
| bool is_history_what_you_typed_match; |
| }; |
| |
| AutocompleteResult(); |
| ~AutocompleteResult(); |
| |
| // operator=() by another name. |
| void CopyFrom(const AutocompleteResult& rhs); |
| |
| // Copies matches from |old_matches| to provide a consistant result set. See |
| // comments in code for specifics. |
| void CopyOldMatches(const AutocompleteInput& input, |
| const AutocompleteResult& old_matches); |
| |
| // Adds a single match. The match is inserted at the appropriate position |
| // based on relevancy and display order. This is ONLY for use after |
| // SortAndCull() has been invoked, and preserves default_match_. |
| void AddMatch(const AutocompleteMatch& match); |
| |
| // Adds a new set of matches to the result set. Does not re-sort. |
| void AppendMatches(const ACMatches& matches); |
| |
| // Removes duplicates, puts the list in sorted order and culls to leave only |
| // the best kMaxMatches matches. Sets the default match to the best match |
| // and updates the alternate nav URL. |
| void SortAndCull(const AutocompleteInput& input); |
| |
| // Returns true if at least one match was copied from the last result. |
| bool HasCopiedMatches() const; |
| |
| // Vector-style accessors/operators. |
| size_t size() const; |
| bool empty() const; |
| const_iterator begin() const; |
| iterator begin(); |
| const_iterator end() const; |
| iterator end(); |
| |
| // Returns the match at the given index. |
| const AutocompleteMatch& match_at(size_t index) const; |
| |
| // Get the default match for the query (not necessarily the first). Returns |
| // end() if there is no default match. |
| const_iterator default_match() const { return default_match_; } |
| |
| GURL alternate_nav_url() const { return alternate_nav_url_; } |
| |
| // Clears the matches for this result set. |
| void Reset(); |
| |
| void Swap(AutocompleteResult* other); |
| |
| #ifndef NDEBUG |
| // Does a data integrity check on this result. |
| void Validate() const; |
| #endif |
| |
| // Max number of matches we'll show from the various providers. |
| static const size_t kMaxMatches; |
| |
| private: |
| typedef std::map<AutocompleteProvider*, ACMatches> ProviderToMatches; |
| |
| // Populates |provider_to_matches| from |matches_|. |
| void BuildProviderToMatches(ProviderToMatches* provider_to_matches) const; |
| |
| // Returns true if |matches| contains a match with the same destination as |
| // |match|. |
| static bool HasMatchByDestination(const AutocompleteMatch& match, |
| const ACMatches& matches); |
| |
| // Copies matches into this result. |old_matches| gives the matches from the |
| // last result, and |new_matches| the results from this result. |
| void MergeMatchesByProvider(const ACMatches& old_matches, |
| const ACMatches& new_matches); |
| |
| ACMatches matches_; |
| |
| const_iterator default_match_; |
| |
| // The "alternate navigation URL", if any, for this result set. This is a URL |
| // to try offering as a navigational option in case the user navigated to the |
| // URL of the default match but intended something else. For example, if the |
| // user's local intranet contains site "foo", and the user types "foo", we |
| // default to searching for "foo" when the user may have meant to navigate |
| // there. In cases like this, the default match will point to the "search for |
| // 'foo'" result, and this will contain "http://foo/". |
| GURL alternate_nav_url_; |
| |
| DISALLOW_COPY_AND_ASSIGN(AutocompleteResult); |
| }; |
| |
| // AutocompleteController ----------------------------------------------------- |
| |
| // The coordinator for autocomplete queries, responsible for combining the |
| // matches from a series of providers into one AutocompleteResult. |
| class AutocompleteController : public ACProviderListener { |
| public: |
| // Used to indicate an index that is not selected in a call to Update(). |
| static const int kNoItemSelected; |
| |
| // Normally, you will call the first constructor. Unit tests can use the |
| // second to set the providers to some known testing providers. The default |
| // providers will be overridden and the controller will take ownership of the |
| // providers, Release()ing them on destruction. |
| AutocompleteController(Profile* profile, |
| AutocompleteControllerDelegate* delegate); |
| #ifdef UNIT_TEST |
| explicit AutocompleteController(const ACProviders& providers) |
| : delegate_(NULL), |
| providers_(providers), |
| search_provider_(NULL), |
| done_(true), |
| in_start_(false) { |
| } |
| #endif |
| ~AutocompleteController(); |
| |
| // Invoked when the profile changes. This forwards the call down to all |
| // the AutocompleteProviders. |
| void SetProfile(Profile* profile); |
| |
| // Starts an autocomplete query, which continues until all providers are |
| // done or the query is Stop()ed. It is safe to Start() a new query without |
| // Stop()ing the previous one. |
| // |
| // See AutocompleteInput::desired_tld() for meaning of |desired_tld|. |
| // |
| // |prevent_inline_autocomplete| is true if the generated result set should |
| // not require inline autocomplete for the default match. This is difficult |
| // to explain in the abstract; the practical use case is that after the user |
| // deletes text in the edit, the HistoryURLProvider should make sure not to |
| // promote a match requiring inline autocomplete too highly. |
| // |
| // |prefer_keyword| should be true when the keyword UI is onscreen; this will |
| // bias the autocomplete result set toward the keyword provider when the input |
| // string is a bare keyword. |
| // |
| // |allow_exact_keyword_match| should be false when triggering keyword mode on |
| // the input string would be surprising or wrong, e.g. when highlighting text |
| // in a page and telling the browser to search for it or navigate to it. This |
| // parameter only applies to substituting keywords. |
| |
| // If |matches_requested| is BEST_MATCH or SYNCHRONOUS_MATCHES the controller |
| // asks the providers to only return matches which are synchronously |
| // available, which should mean that all providers will be done immediately. |
| // |
| // The controller calls AutocompleteControllerDelegate::OnResultChanged() from |
| // inside this call at least once. If matches are available later on that |
| // result in changing the result set the delegate is notified again. When the |
| // controller is done the notification AUTOCOMPLETE_CONTROLLER_RESULT_READY is |
| // sent. |
| void Start(const string16& text, |
| const string16& desired_tld, |
| bool prevent_inline_autocomplete, |
| bool prefer_keyword, |
| bool allow_exact_keyword_match, |
| AutocompleteInput::MatchesRequested matches_requested); |
| |
| // Cancels the current query, ensuring there will be no future notifications |
| // fired. If new matches have come in since the most recent notification was |
| // fired, they will be discarded. |
| // |
| // If |clear_result| is true, the controller will also erase the result set. |
| void Stop(bool clear_result); |
| |
| // Asks the relevant provider to delete |match|, and ensures observers are |
| // notified of resulting changes immediately. This should only be called when |
| // no query is running. |
| void DeleteMatch(const AutocompleteMatch& match); |
| |
| // Removes any entries that were copied from the last result. This is used by |
| // the popup to ensure it's not showing an out-of-date query. |
| void ExpireCopiedEntries(); |
| |
| SearchProvider* search_provider() const { return search_provider_; } |
| |
| // Getters |
| const AutocompleteInput& input() const { return input_; } |
| const AutocompleteResult& result() const { return result_; } |
| bool done() const { return done_; } |
| |
| // From AutocompleteProvider::Listener |
| virtual void OnProviderUpdate(bool updated_matches); |
| |
| private: |
| // Updates |result_| to reflect the current provider state. Resets timers and |
| // fires notifications as necessary. |is_synchronous_pass| is true only when |
| // Start() is calling this to get the synchronous result. |
| void UpdateResult(bool is_synchronous_pass); |
| |
| // Calls AutocompleteControllerDelegate::OnResultChanged() and if done sends |
| // AUTOCOMPLETE_CONTROLLER_RESULT_READY. |
| void NotifyChanged(bool notify_default_match); |
| |
| // Updates |done_| to be accurate with respect to current providers' statuses. |
| void CheckIfDone(); |
| |
| // Starts the expire timer. |
| void StartExpireTimer(); |
| |
| AutocompleteControllerDelegate* delegate_; |
| |
| // A list of all providers. |
| ACProviders providers_; |
| |
| SearchProvider* search_provider_; |
| |
| // Input passed to Start. |
| AutocompleteInput input_; |
| |
| // Data from the autocomplete query. |
| AutocompleteResult result_; |
| |
| // Timer used to remove any matches copied from the last result. When run |
| // invokes |ExpireCopiedEntries|. |
| base::OneShotTimer<AutocompleteController> expire_timer_; |
| |
| // True if a query is not currently running. |
| bool done_; |
| |
| // Are we in Start()? This is used to avoid updating |result_| and sending |
| // notifications until Start() has been invoked on all providers. |
| bool in_start_; |
| |
| DISALLOW_COPY_AND_ASSIGN(AutocompleteController); |
| }; |
| |
| // AutocompleteLog ------------------------------------------------------------ |
| |
| // The data to log (via the metrics service) when the user selects an item |
| // from the omnibox popup. |
| struct AutocompleteLog { |
| AutocompleteLog(const string16& text, |
| AutocompleteInput::Type input_type, |
| size_t selected_index, |
| size_t inline_autocompleted_length, |
| const AutocompleteResult& result) |
| : text(text), |
| input_type(input_type), |
| selected_index(selected_index), |
| inline_autocompleted_length(inline_autocompleted_length), |
| result(result) { |
| } |
| // The user's input text in the omnibox. |
| string16 text; |
| // The detected type of the user's input. |
| AutocompleteInput::Type input_type; |
| // Selected index (if selected) or -1 (AutocompletePopupModel::kNoMatch). |
| size_t selected_index; |
| // Inline autocompleted length (if displayed). |
| size_t inline_autocompleted_length; |
| // Result set. |
| const AutocompleteResult& result; |
| }; |
| |
| #endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_H_ |