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