• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
6 #define CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
7 
8 #include <string>
9 #include <utility>
10 #include <vector>
11 
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/time/time.h"
15 #include "chrome/browser/autocomplete/autocomplete_input.h"
16 #include "chrome/browser/search_engines/template_url_id.h"
17 #include "ui/gfx/size.h"
18 #include "url/gurl.h"
19 #include "url/url_parse.h"
20 
21 class Profile;
22 class SearchTermsData;
23 class TemplateURL;
24 
25 
26 // TemplateURLRef -------------------------------------------------------------
27 
28 // A TemplateURLRef represents a single URL within the larger TemplateURL class
29 // (which represents an entire "search engine", see below).  If
30 // SupportsReplacement() is true, this URL has placeholders in it, for which
31 // callers can substitute values to get a "real" URL using ReplaceSearchTerms().
32 //
33 // TemplateURLRefs always have a non-NULL |owner_| TemplateURL, which they
34 // access in order to get at important data like the underlying URL string or
35 // the associated Profile.
36 class TemplateURLRef {
37  public:
38   // Magic numbers to pass to ReplaceSearchTerms() for the |accepted_suggestion|
39   // parameter.  Most callers aren't using Suggest capabilities and should just
40   // pass NO_SUGGESTIONS_AVAILABLE.
41   // NOTE: Because positive values are meaningful, make sure these are negative!
42   enum AcceptedSuggestion {
43     NO_SUGGESTION_CHOSEN = -1,
44     NO_SUGGESTIONS_AVAILABLE = -2,
45   };
46 
47   // Which kind of URL within our owner we are.  This allows us to get at the
48   // correct string field. Use |INDEXED| to indicate that the numerical
49   // |index_in_owner_| should be used instead.
50   enum Type {
51     SEARCH,
52     SUGGEST,
53     INSTANT,
54     IMAGE,
55     NEW_TAB,
56     INDEXED
57   };
58 
59   // Type to store <content_type, post_data> pair for POST URLs.
60   // The |content_type|(first part of the pair) is the content-type of
61   // the |post_data|(second part of the pair) which is encoded in
62   // "multipart/form-data" format, it also contains the MIME boundary used in
63   // the |post_data|. See http://tools.ietf.org/html/rfc2046 for the details.
64   typedef std::pair<std::string, std::string> PostContent;
65 
66   // This struct encapsulates arguments passed to
67   // TemplateURLRef::ReplaceSearchTerms methods.  By default, only search_terms
68   // is required and is passed in the constructor.
69   struct SearchTermsArgs {
70     explicit SearchTermsArgs(const base::string16& search_terms);
71     ~SearchTermsArgs();
72 
73     // The search terms (query).
74     base::string16 search_terms;
75 
76     // The original (input) query.
77     base::string16 original_query;
78 
79     // The optional assisted query stats, aka AQS, used for logging purposes.
80     // This string contains impressions of all autocomplete matches shown
81     // at the query submission time.  For privacy reasons, we require the
82     // search provider to support HTTPS protocol in order to receive the AQS
83     // param.
84     // For more details, see http://goto.google.com/binary-clients-logging .
85     std::string assisted_query_stats;
86 
87     // TODO: Remove along with "aq" CGI param.
88     int accepted_suggestion;
89 
90     // The 0-based position of the cursor within the query string at the time
91     // the request was issued.  Set to base::string16::npos if not used.
92     size_t cursor_position;
93 
94     // The start-edge margin of the omnibox in pixels, used in extended Instant
95     // to align the preview contents with the omnibox.
96     int omnibox_start_margin;
97 
98     // The URL of the current webpage to be used for experimental zero-prefix
99     // suggestions.
100     std::string current_page_url;
101 
102     // Which omnibox the user used to type the prefix.
103     AutocompleteInput::PageClassification page_classification;
104 
105     // True for searches issued with the bookmark bar pref set to shown.
106     bool bookmark_bar_pinned;
107 
108     // Additional query params provided by the suggest server.
109     std::string suggest_query_params;
110 
111     // If set, ReplaceSearchTerms() will automatically append any extra query
112     // params specified via the --extra-search-query-params command-line
113     // argument.  Generally, this should be set when dealing with the search or
114     // instant TemplateURLRefs of the default search engine and the caller cares
115     // about the query portion of the URL.  Since neither TemplateURLRef nor
116     // indeed TemplateURL know whether a TemplateURL is the default search
117     // engine, callers instead must set this manually.
118     bool append_extra_query_params;
119 
120     // The raw content of an image thumbnail that will be used as a query for
121     // search-by-image frontend.
122     std::string image_thumbnail_content;
123 
124     // When searching for an image, the URL of the original image. Callers
125     // should leave this empty for images specified via data: URLs.
126     GURL image_url;
127 
128     // When searching for an image, the original size of the image.
129     gfx::Size image_original_size;
130 
131     // If set, ReplaceSearchTerms() will append a param to the TemplateURLRef to
132     // update the search results page incrementally even if that is otherwise
133     // disabled by google.com preferences. See comments on
134     // SearchTermsData::ForceInstantResultsParam().
135     bool force_instant_results;
136   };
137 
138   TemplateURLRef(TemplateURL* owner, Type type);
139   TemplateURLRef(TemplateURL* owner, size_t index_in_owner);
140   ~TemplateURLRef();
141 
142   // Returns the raw URL. None of the parameters will have been replaced.
143   std::string GetURL() const;
144 
145   // Returns the raw string of the post params. Please see comments in
146   // prepopulated_engines_schema.json for the format.
147   std::string GetPostParamsString() const;
148 
149   // Returns true if this URL supports search term replacement.
150   bool SupportsReplacement() const;
151 
152   // Like SupportsReplacement but usable on threads other than the UI thread.
153   bool SupportsReplacementUsingTermsData(
154       const SearchTermsData& search_terms_data) const;
155 
156   // Returns a string that is the result of replacing the search terms in
157   // the url with the specified arguments.  We use our owner's input encoding.
158   //
159   // If this TemplateURLRef does not support replacement (SupportsReplacement
160   // returns false), an empty string is returned.
161   // If this TemplateURLRef uses POST, and |post_content| is not NULL, the
162   // |post_params_| will be replaced, encoded in "multipart/form-data" format
163   // and stored into |post_content|.
164   std::string ReplaceSearchTerms(
165       const SearchTermsArgs& search_terms_args,
166       PostContent* post_content) const;
167   // TODO(jnd): remove the following ReplaceSearchTerms definition which does
168   // not have |post_content| parameter once all reference callers pass
169   // |post_content| parameter.
ReplaceSearchTerms(const SearchTermsArgs & search_terms_args)170   std::string ReplaceSearchTerms(
171       const SearchTermsArgs& search_terms_args) const {
172     return ReplaceSearchTerms(search_terms_args, NULL);
173   }
174 
175   // Just like ReplaceSearchTerms except that it takes SearchTermsData to supply
176   // the data for some search terms. Most of the time ReplaceSearchTerms should
177   // be called.
178   std::string ReplaceSearchTermsUsingTermsData(
179       const SearchTermsArgs& search_terms_args,
180       const SearchTermsData& search_terms_data,
181       PostContent* post_content) const;
182 
183   // Returns true if the TemplateURLRef is valid. An invalid TemplateURLRef is
184   // one that contains unknown terms, or invalid characters.
185   bool IsValid() const;
186 
187   // Like IsValid but usable on threads other than the UI thread.
188   bool IsValidUsingTermsData(const SearchTermsData& search_terms_data) const;
189 
190   // Returns a string representation of this TemplateURLRef suitable for
191   // display. The display format is the same as the format used by Firefox.
192   base::string16 DisplayURL() const;
193 
194   // Converts a string as returned by DisplayURL back into a string as
195   // understood by TemplateURLRef.
196   static std::string DisplayURLToURLRef(const base::string16& display_url);
197 
198   // If this TemplateURLRef is valid and contains one search term, this returns
199   // the host/path of the URL, otherwise this returns an empty string.
200   const std::string& GetHost() const;
201   const std::string& GetPath() const;
202 
203   // If this TemplateURLRef is valid and contains one search term, this returns
204   // the key of the search term, otherwise this returns an empty string.
205   const std::string& GetSearchTermKey() const;
206 
207   // Converts the specified term in our owner's encoding to a base::string16.
208   base::string16 SearchTermToString16(const std::string& term) const;
209 
210   // Returns true if this TemplateURLRef has a replacement term of
211   // {google:baseURL} or {google:baseSuggestURL}.
212   bool HasGoogleBaseURLs() const;
213 
214   // Use the pattern referred to by this TemplateURLRef to match the provided
215   // |url| and extract |search_terms| from it. Returns true if the pattern
216   // matches, even if |search_terms| is empty. In this case
217   // |search_term_component|, if not NULL, indicates whether the search terms
218   // were found in the query or the ref parameters; and |search_terms_position|,
219   // if not NULL, contains the position of the search terms in the query or the
220   // ref parameters. Returns false and an empty |search_terms| if the pattern
221   // does not match.
222   bool ExtractSearchTermsFromURL(
223       const GURL& url,
224       base::string16* search_terms,
225       const SearchTermsData& search_terms_data,
226       url_parse::Parsed::ComponentType* search_term_component,
227       url_parse::Component* search_terms_position) const;
228 
229   // Whether the URL uses POST (as opposed to GET).
230   bool UsesPOSTMethodUsingTermsData(
231       const SearchTermsData* search_terms_data) const;
UsesPOSTMethod()232   bool UsesPOSTMethod() const {
233     return UsesPOSTMethodUsingTermsData(NULL);
234   }
235 
236  private:
237   friend class TemplateURL;
238   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, SetPrepopulatedAndParse);
239   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterKnown);
240   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterUnknown);
241   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLEmpty);
242   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoTemplateEnd);
243   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoKnownParameters);
244   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLTwoParameters);
245   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNestedParameter);
246   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, URLRefTestImageURLWithPOST);
247   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ReflectsBookmarkBarPinned);
248 
249   // Enumeration of the known types.
250   enum ReplacementType {
251     ENCODING,
252     GOOGLE_ASSISTED_QUERY_STATS,
253     GOOGLE_BASE_URL,
254     GOOGLE_BASE_SUGGEST_URL,
255     GOOGLE_BOOKMARK_BAR_PINNED,
256     GOOGLE_CURRENT_PAGE_URL,
257     GOOGLE_CURSOR_POSITION,
258     GOOGLE_IMAGE_ORIGINAL_HEIGHT,
259     GOOGLE_IMAGE_ORIGINAL_WIDTH,
260     GOOGLE_IMAGE_SEARCH_SOURCE,
261     GOOGLE_IMAGE_THUMBNAIL,
262     GOOGLE_IMAGE_URL,
263     GOOGLE_FORCE_INSTANT_RESULTS,
264     GOOGLE_INSTANT_EXTENDED_ENABLED,
265     GOOGLE_NTP_IS_THEMED,
266     GOOGLE_OMNIBOX_START_MARGIN,
267     GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION,
268     GOOGLE_PAGE_CLASSIFICATION,
269     GOOGLE_RLZ,
270     GOOGLE_SEARCH_CLIENT,
271     GOOGLE_SEARCH_FIELDTRIAL_GROUP,
272     GOOGLE_SUGGEST_CLIENT,
273     GOOGLE_SUGGEST_REQUEST_ID,
274     GOOGLE_UNESCAPED_SEARCH_TERMS,
275     LANGUAGE,
276     SEARCH_TERMS,
277   };
278 
279   // Used to identify an element of the raw url that can be replaced.
280   struct Replacement {
ReplacementReplacement281     Replacement(ReplacementType type, size_t index)
282         : type(type), index(index), is_post_param(false) {}
283     ReplacementType type;
284     size_t index;
285     // Indicates the location in where the replacement is replaced. If
286     // |is_post_param| is false, |index| indicates the byte position in
287     // |parsed_url_|. Otherwise, |index| is the index of |post_params_|.
288     bool is_post_param;
289   };
290 
291   // The list of elements to replace.
292   typedef std::vector<struct Replacement> Replacements;
293   // Type to store <key, value> pairs for POST URLs.
294   typedef std::pair<std::string, std::string> PostParam;
295   typedef std::vector<PostParam> PostParams;
296 
297   // TemplateURLRef internally caches values to make replacement quick. This
298   // method invalidates any cached values.
299   void InvalidateCachedValues() const;
300 
301   // Parses the parameter in url at the specified offset. start/end specify the
302   // range of the parameter in the url, including the braces. If the parameter
303   // is valid, url is updated to reflect the appropriate parameter. If
304   // the parameter is one of the known parameters an element is added to
305   // replacements indicating the type and range of the element. The original
306   // parameter is erased from the url.
307   //
308   // If the parameter is not a known parameter, false is returned. If this is a
309   // prepopulated URL, the parameter is erased, otherwise it is left alone.
310   bool ParseParameter(size_t start,
311                       size_t end,
312                       std::string* url,
313                       Replacements* replacements) const;
314 
315   // Parses the specified url, replacing parameters as necessary. If
316   // successful, valid is set to true, and the parsed url is returned. For all
317   // known parameters that are encountered an entry is added to replacements.
318   // If there is an error parsing the url, valid is set to false, and an empty
319   // string is returned.  If the URL has the POST parameters, they will be
320   // parsed into |post_params| which will be further replaced with real search
321   // terms data and encoded in "multipart/form-data" format to generate the
322   // POST data.
323   std::string ParseURL(const std::string& url,
324                        Replacements* replacements,
325                        PostParams* post_params,
326                        bool* valid) const;
327 
328   // If the url has not yet been parsed, ParseURL is invoked.
329   // NOTE: While this is const, it modifies parsed_, valid_, parsed_url_ and
330   // search_offset_.
331   void ParseIfNecessary() const;
332 
333   // Like ParseIfNecessary but usable on threads other than the UI thread.
334   void ParseIfNecessaryUsingTermsData(
335       const SearchTermsData& search_terms_data) const;
336 
337   // Extracts the query key and host from the url.
338   void ParseHostAndSearchTermKey(
339       const SearchTermsData& search_terms_data) const;
340 
341   // Encode post parameters in "multipart/form-data" format and store it
342   // inside |post_content|. Returns false if errors are encountered during
343   // encoding. This method is called each time ReplaceSearchTerms gets called.
344   bool EncodeFormData(const PostParams& post_params,
345                       PostContent* post_content) const;
346 
347   // Handles a replacement by using real term data. If the replacement
348   // belongs to a PostParam, the PostParam will be replaced by the term data.
349   // Otherwise, the term data will be inserted at the place that the
350   // replacement points to.
351   void HandleReplacement(const std::string& name,
352                          const std::string& value,
353                          const Replacement& replacement,
354                          std::string* url) const;
355 
356   // Replaces all replacements in |parsed_url_| with their actual values and
357   // returns the result.  This is the main functionality of
358   // ReplaceSearchTermsUsingTermsData().
359   std::string HandleReplacements(
360       const SearchTermsArgs& search_terms_args,
361       const SearchTermsData& search_terms_data,
362       PostContent* post_content) const;
363 
364   // The TemplateURL that contains us.  This should outlive us.
365   TemplateURL* const owner_;
366 
367   // What kind of URL we are.
368   const Type type_;
369 
370   // If |type_| is |INDEXED|, this |index_in_owner_| is used instead to refer to
371   // a url within our owner.
372   const size_t index_in_owner_;
373 
374   // Whether the URL has been parsed.
375   mutable bool parsed_;
376 
377   // Whether the url was successfully parsed.
378   mutable bool valid_;
379 
380   // The parsed URL. All terms have been stripped out of this with
381   // replacements_ giving the index of the terms to replace.
382   mutable std::string parsed_url_;
383 
384   // Do we support search term replacement?
385   mutable bool supports_replacements_;
386 
387   // The replaceable parts of url (parsed_url_). These are ordered by index
388   // into the string, and may be empty.
389   mutable Replacements replacements_;
390 
391   // Host, path, key and location of the search term. These are only set if the
392   // url contains one search term.
393   mutable std::string host_;
394   mutable std::string path_;
395   mutable std::string search_term_key_;
396   mutable url_parse::Parsed::ComponentType search_term_key_location_;
397 
398   mutable PostParams post_params_;
399 
400   // Whether the contained URL is a pre-populated URL.
401   bool prepopulated_;
402 
403   // Whether search terms are shown in the omnibox on search results pages.
404   // This is kept as a member so it can be overridden by tests.
405   bool showing_search_terms_;
406 
407   DISALLOW_COPY_AND_ASSIGN(TemplateURLRef);
408 };
409 
410 
411 // TemplateURLData ------------------------------------------------------------
412 
413 // The data for the TemplateURL.  Separating this into its own class allows most
414 // users to do SSA-style usage of TemplateURL: construct a TemplateURLData with
415 // whatever fields are desired, then create an immutable TemplateURL from it.
416 struct TemplateURLData {
417   TemplateURLData();
418   ~TemplateURLData();
419 
420   // A short description of the template. This is the name we show to the user
421   // in various places that use TemplateURLs. For example, the location bar
422   // shows this when the user selects a substituting match.
423   base::string16 short_name;
424 
425   // The shortcut for this TemplateURL.  |keyword| must be non-empty.
426   void SetKeyword(const base::string16& keyword);
keywordTemplateURLData427   const base::string16& keyword() const { return keyword_; }
428 
429   // The raw URL for the TemplateURL, which may not be valid as-is (e.g. because
430   // it requires substitutions first).  This must be non-empty.
431   void SetURL(const std::string& url);
urlTemplateURLData432   const std::string& url() const { return url_; }
433 
434   // Optional additional raw URLs.
435   std::string suggestions_url;
436   std::string instant_url;
437   std::string image_url;
438   std::string new_tab_url;
439 
440   // The following post_params are comma-separated lists used to specify the
441   // post parameters for the corresponding URL.
442   std::string search_url_post_params;
443   std::string suggestions_url_post_params;
444   std::string instant_url_post_params;
445   std::string image_url_post_params;
446 
447   // Optional favicon for the TemplateURL.
448   GURL favicon_url;
449 
450   // URL to the OSD file this came from. May be empty.
451   GURL originating_url;
452 
453   // Whether this TemplateURL is shown in the default list of search providers.
454   // This is just a property and does not indicate whether the TemplateURL has a
455   // TemplateURLRef that supports replacement. Use
456   // TemplateURL::ShowInDefaultList() to test both.
457   bool show_in_default_list;
458 
459   // Whether it's safe for auto-modification code (the autogenerator and the
460   // code that imports data from other browsers) to replace the TemplateURL.
461   // This should be set to false for any TemplateURL the user edits, or any
462   // TemplateURL that the user clearly manually edited in the past, like a
463   // bookmark keyword from another browser.
464   bool safe_for_autoreplace;
465 
466   // The list of supported encodings for the search terms. This may be empty,
467   // which indicates the terms should be encoded with UTF-8.
468   std::vector<std::string> input_encodings;
469 
470   // Unique identifier of this TemplateURL. The unique ID is set by the
471   // TemplateURLService when the TemplateURL is added to it.
472   TemplateURLID id;
473 
474   // Date this TemplateURL was created.
475   //
476   // NOTE: this may be 0, which indicates the TemplateURL was created before we
477   // started tracking creation time.
478   base::Time date_created;
479 
480   // The last time this TemplateURL was modified by a user, since creation.
481   //
482   // NOTE: Like date_created above, this may be 0.
483   base::Time last_modified;
484 
485   // True if this TemplateURL was automatically created by the administrator via
486   // group policy.
487   bool created_by_policy;
488 
489   // Number of times this TemplateURL has been explicitly used to load a URL.
490   // We don't increment this for uses as the "default search engine" since
491   // that's not really "explicit" usage and incrementing would result in pinning
492   // the user's default search engine(s) to the top of the list of searches on
493   // the New Tab page, de-emphasizing the omnibox as "where you go to search".
494   int usage_count;
495 
496   // If this TemplateURL comes from prepopulated data the prepopulate_id is > 0.
497   int prepopulate_id;
498 
499   // The primary unique identifier for Sync. This set on all TemplateURLs
500   // regardless of whether they have been associated with Sync.
501   std::string sync_guid;
502 
503   // A list of URL patterns that can be used, in addition to |url_|, to extract
504   // search terms from a URL.
505   std::vector<std::string> alternate_urls;
506 
507   // A parameter that, if present in the query or ref parameters of a search_url
508   // or instant_url, causes Chrome to replace the URL with the search term.
509   std::string search_terms_replacement_key;
510 
511  private:
512   // Private so we can enforce using the setters and thus enforce that these
513   // fields are never empty.
514   base::string16 keyword_;
515   std::string url_;
516 };
517 
518 
519 // AssociatedExtensionInfo ----------------------------------------------------
520 
521 // An AssociatedExtensionInfo represents information about the extension that
522 // added the search engine using the Override Settings API.
523 struct AssociatedExtensionInfo {
524   std::string extension_id;
525 
526   // Whether the search engine is supposed to be default.
527   bool wants_to_be_default_engine;
528 
529   // Used to resolve conflicts when there are multiple extensions specifying the
530   // default search engine. The most recently-installed wins.
531   base::Time install_time;
532 };
533 
534 
535 // TemplateURL ----------------------------------------------------------------
536 
537 // A TemplateURL represents a single "search engine", defined primarily as a
538 // subset of the Open Search Description Document
539 // (http://www.opensearch.org/Specifications/OpenSearch) plus some extensions.
540 // One TemplateURL contains several TemplateURLRefs, which correspond to various
541 // different capabilities (e.g. doing searches or getting suggestions), as well
542 // as a TemplateURLData containing other details like the name, keyword, etc.
543 //
544 // TemplateURLs are intended to be read-only for most users; the only public
545 // non-const method is the Profile getter, which returns a non-const Profile*.
546 // The TemplateURLService, which handles storing and manipulating TemplateURLs,
547 // is made a friend so that it can be the exception to this pattern.
548 class TemplateURL {
549  public:
550   enum Type {
551     // Regular search engine.
552     NORMAL,
553     // Installed by extension through Override Settings API.
554     NORMAL_CONTROLLED_BY_EXTENSION,
555     // The keyword associated with an extension that uses the Omnibox API.
556     OMNIBOX_API_EXTENSION,
557   };
558   // |profile| may be NULL.  This will affect the results of e.g. calling
559   // ReplaceSearchTerms() on the member TemplateURLRefs.
560   TemplateURL(Profile* profile, const TemplateURLData& data);
561   ~TemplateURL();
562 
563   // Generates a favicon URL from the specified url.
564   static GURL GenerateFaviconURL(const GURL& url);
565 
profile()566   Profile* profile() { return profile_; }
data()567   const TemplateURLData& data() const { return data_; }
568 
short_name()569   const base::string16& short_name() const { return data_.short_name; }
570   // An accessor for the short_name, but adjusted so it can be appropriately
571   // displayed even if it is LTR and the UI is RTL.
572   base::string16 AdjustedShortNameForLocaleDirection() const;
573 
keyword()574   const base::string16& keyword() const { return data_.keyword(); }
575 
url()576   const std::string& url() const { return data_.url(); }
suggestions_url()577   const std::string& suggestions_url() const { return data_.suggestions_url; }
instant_url()578   const std::string& instant_url() const { return data_.instant_url; }
image_url()579   const std::string& image_url() const { return data_.image_url; }
new_tab_url()580   const std::string& new_tab_url() const { return data_.new_tab_url; }
search_url_post_params()581   const std::string& search_url_post_params() const {
582     return data_.search_url_post_params;
583   }
suggestions_url_post_params()584   const std::string& suggestions_url_post_params() const {
585     return data_.suggestions_url_post_params;
586   }
instant_url_post_params()587   const std::string& instant_url_post_params() const {
588     return data_.instant_url_post_params;
589   }
image_url_post_params()590   const std::string& image_url_post_params() const {
591     return data_.image_url_post_params;
592   }
alternate_urls()593   const std::vector<std::string>& alternate_urls() const {
594     return data_.alternate_urls;
595   }
favicon_url()596   const GURL& favicon_url() const { return data_.favicon_url; }
597 
originating_url()598   const GURL& originating_url() const { return data_.originating_url; }
599 
show_in_default_list()600   bool show_in_default_list() const { return data_.show_in_default_list; }
601   // Returns true if show_in_default_list() is true and this TemplateURL has a
602   // TemplateURLRef that supports replacement.
603   bool ShowInDefaultList() const;
604 
safe_for_autoreplace()605   bool safe_for_autoreplace() const { return data_.safe_for_autoreplace; }
606 
input_encodings()607   const std::vector<std::string>& input_encodings() const {
608     return data_.input_encodings;
609   }
610 
id()611   TemplateURLID id() const { return data_.id; }
612 
date_created()613   base::Time date_created() const { return data_.date_created; }
last_modified()614   base::Time last_modified() const { return data_.last_modified; }
615 
created_by_policy()616   bool created_by_policy() const { return data_.created_by_policy; }
617 
usage_count()618   int usage_count() const { return data_.usage_count; }
619 
prepopulate_id()620   int prepopulate_id() const { return data_.prepopulate_id; }
621 
sync_guid()622   const std::string& sync_guid() const { return data_.sync_guid; }
623 
624   // TODO(beaudoin): Rename this when renaming HasSearchTermsReplacementKey().
search_terms_replacement_key()625   const std::string& search_terms_replacement_key() const {
626     return data_.search_terms_replacement_key;
627   }
628 
url_ref()629   const TemplateURLRef& url_ref() const { return url_ref_; }
suggestions_url_ref()630   const TemplateURLRef& suggestions_url_ref() const {
631     return suggestions_url_ref_;
632   }
instant_url_ref()633   const TemplateURLRef& instant_url_ref() const { return instant_url_ref_; }
image_url_ref()634   const TemplateURLRef& image_url_ref() const { return image_url_ref_; }
new_tab_url_ref()635   const TemplateURLRef& new_tab_url_ref() const { return new_tab_url_ref_; }
636 
637   // Returns true if |url| supports replacement.
638   bool SupportsReplacement() const;
639 
640   // Like SupportsReplacement but usable on threads other than the UI thread.
641   bool SupportsReplacementUsingTermsData(
642       const SearchTermsData& search_terms_data) const;
643 
644   // Returns true if this TemplateURL uses Google base URLs and has a keyword
645   // of "google.TLD".  We use this to decide whether we can automatically
646   // update the keyword to reflect the current Google base URL TLD.
647   bool IsGoogleSearchURLWithReplaceableKeyword() const;
648 
649   // Returns true if the keywords match or if
650   // IsGoogleSearchURLWithReplaceableKeyword() is true for both TemplateURLs.
651   bool HasSameKeywordAs(const TemplateURL& other) const;
652 
653   Type GetType() const;
654 
655   // Returns the id of the extension that added this search engine. Only call
656   // this for TemplateURLs of type NORMAL_CONTROLLED_BY_EXTENSION or
657   // OMNIBOX_API_EXTENSION.
658   std::string GetExtensionId() const;
659 
660   // Returns the total number of URLs comprised in this template, including
661   // search and alternate URLs.
662   size_t URLCount() const;
663 
664   // Gets the search URL at the given index. The alternate URLs, if any, are
665   // numbered starting at 0, and the primary search URL follows. This is used
666   // to decode the search term given a search URL (see
667   // ExtractSearchTermsFromURL()).
668   const std::string& GetURL(size_t index) const;
669 
670   // Use the alternate URLs and the search URL to match the provided |url|
671   // and extract |search_terms| from it. Returns false and an empty
672   // |search_terms| if no search terms can be matched. The order in which the
673   // alternate URLs are listed dictates their priority, the URL at index 0 is
674   // treated as the highest priority and the primary search URL is treated as
675   // the lowest priority (see GetURL()).  For example, if a TemplateURL has
676   // alternate URL "http://foo/#q={searchTerms}" and search URL
677   // "http://foo/?q={searchTerms}", and the URL to be decoded is
678   // "http://foo/?q=a#q=b", the alternate URL will match first and the decoded
679   // search term will be "b".
680   bool ExtractSearchTermsFromURL(const GURL& url, base::string16* search_terms);
681 
682   // Like ExtractSearchTermsFromURL but usable on threads other than the UI
683   // thread.
684   bool ExtractSearchTermsFromURLUsingTermsData(
685       const GURL& url,
686       base::string16* search_terms,
687       const SearchTermsData& search_terms_data);
688 
689   // Returns true if non-empty search terms could be extracted from |url| using
690   // ExtractSearchTermsFromURL(). In other words, this returns whether |url|
691   // could be the result of performing a search with |this|.
692   bool IsSearchURL(const GURL& url);
693 
694   // Like IsSearchURL but usable on threads other than the UI thread.
695   bool IsSearchURLUsingTermsData(
696       const GURL& url,
697       const SearchTermsData& search_terms_data);
698 
699   // Returns true if the specified |url| contains the search terms replacement
700   // key in either the query or the ref. This method does not verify anything
701   // else about the URL. In particular, it does not check that the domain
702   // matches that of this TemplateURL.
703   // TODO(beaudoin): Rename this to reflect that it really checks for an
704   // InstantExtended capable URL.
705   bool HasSearchTermsReplacementKey(const GURL& url) const;
706 
707   // Given a |url| corresponding to this TemplateURL, identifies the search
708   // terms and replaces them with the ones in |search_terms_args|, leaving the
709   // other parameters untouched. If the replacement fails, returns false and
710   // leaves |result| untouched. This is used by mobile ports to perform query
711   // refinement.
712   bool ReplaceSearchTermsInURL(
713       const GURL& url,
714       const TemplateURLRef::SearchTermsArgs& search_terms_args,
715       GURL* result);
716 
717   // Encodes the search terms from |search_terms_args| so that we know the
718   // |input_encoding|. Returns the |encoded_terms| and the
719   // |encoded_original_query|. |encoded_terms| may be escaped as path or query
720   // depending on |is_in_query|; |encoded_original_query| is always escaped as
721   // query.
722   void EncodeSearchTerms(
723       const TemplateURLRef::SearchTermsArgs& search_terms_args,
724       bool is_in_query,
725       std::string* input_encoding,
726       base::string16* encoded_terms,
727       base::string16* encoded_original_query) const;
728 
729  private:
730   friend class TemplateURLService;
731   FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ReflectsBookmarkBarPinned);
732 
733   void CopyFrom(const TemplateURL& other);
734 
735   void SetURL(const std::string& url);
736   void SetPrepopulateId(int id);
737 
738   // Resets the keyword if IsGoogleSearchURLWithReplaceableKeyword() or |force|.
739   // The |force| parameter is useful when the existing keyword is known to be
740   // a placeholder.  The resulting keyword is generated using
741   // TemplateURLService::GenerateSearchURL() and
742   // TemplateURLService::GenerateKeyword().
743   void ResetKeywordIfNecessary(bool force);
744 
745   // Uses the alternate URLs and the search URL to match the provided |url|
746   // and extract |search_terms| from it as well as the |search_terms_component|
747   // (either REF or QUERY) and |search_terms_component| at which the
748   // |search_terms| are found in |url|. See also ExtractSearchTermsFromURL().
749   bool FindSearchTermsInURL(
750       const GURL& url,
751       const SearchTermsData& search_terms_data,
752       base::string16* search_terms,
753       url_parse::Parsed::ComponentType* search_terms_component,
754       url_parse::Component* search_terms_position);
755 
756   Profile* profile_;
757   TemplateURLData data_;
758   TemplateURLRef url_ref_;
759   TemplateURLRef suggestions_url_ref_;
760   TemplateURLRef instant_url_ref_;
761   TemplateURLRef image_url_ref_;
762   TemplateURLRef new_tab_url_ref_;
763   scoped_ptr<AssociatedExtensionInfo> extension_info_;
764 
765   // TODO(sky): Add date last parsed OSD file.
766 
767   DISALLOW_COPY_AND_ASSIGN(TemplateURL);
768 };
769 
770 #endif  // CHROME_BROWSER_SEARCH_ENGINES_TEMPLATE_URL_H_
771