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