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. ReplaceSearchTerms(const SearchTermsArgs & search_terms_args,const SearchTermsData & search_terms_data)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 { ReplacementReplacement316 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 data()497 const TemplateURLData& data() const { return data_; } 498 short_name()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 keyword()504 const base::string16& keyword() const { return data_.keyword(); } 505 url()506 const std::string& url() const { return data_.url(); } suggestions_url()507 const std::string& suggestions_url() const { return data_.suggestions_url; } instant_url()508 const std::string& instant_url() const { return data_.instant_url; } image_url()509 const std::string& image_url() const { return data_.image_url; } new_tab_url()510 const std::string& new_tab_url() const { return data_.new_tab_url; } contextual_search_url()511 const std::string& contextual_search_url() const { 512 return data_.contextual_search_url; 513 } search_url_post_params()514 const std::string& search_url_post_params() const { 515 return data_.search_url_post_params; 516 } suggestions_url_post_params()517 const std::string& suggestions_url_post_params() const { 518 return data_.suggestions_url_post_params; 519 } instant_url_post_params()520 const std::string& instant_url_post_params() const { 521 return data_.instant_url_post_params; 522 } image_url_post_params()523 const std::string& image_url_post_params() const { 524 return data_.image_url_post_params; 525 } alternate_urls()526 const std::vector<std::string>& alternate_urls() const { 527 return data_.alternate_urls; 528 } favicon_url()529 const GURL& favicon_url() const { return data_.favicon_url; } 530 originating_url()531 const GURL& originating_url() const { return data_.originating_url; } 532 show_in_default_list()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 safe_for_autoreplace()538 bool safe_for_autoreplace() const { return data_.safe_for_autoreplace; } 539 input_encodings()540 const std::vector<std::string>& input_encodings() const { 541 return data_.input_encodings; 542 } 543 id()544 TemplateURLID id() const { return data_.id; } 545 date_created()546 base::Time date_created() const { return data_.date_created; } last_modified()547 base::Time last_modified() const { return data_.last_modified; } 548 created_by_policy()549 bool created_by_policy() const { return data_.created_by_policy; } 550 usage_count()551 int usage_count() const { return data_.usage_count; } 552 prepopulate_id()553 int prepopulate_id() const { return data_.prepopulate_id; } 554 sync_guid()555 const std::string& sync_guid() const { return data_.sync_guid; } 556 557 // TODO(beaudoin): Rename this when renaming HasSearchTermsReplacementKey(). search_terms_replacement_key()558 const std::string& search_terms_replacement_key() const { 559 return data_.search_terms_replacement_key; 560 } 561 url_ref()562 const TemplateURLRef& url_ref() const { return url_ref_; } suggestions_url_ref()563 const TemplateURLRef& suggestions_url_ref() const { 564 return suggestions_url_ref_; 565 } instant_url_ref()566 const TemplateURLRef& instant_url_ref() const { return instant_url_ref_; } image_url_ref()567 const TemplateURLRef& image_url_ref() const { return image_url_ref_; } new_tab_url_ref()568 const TemplateURLRef& new_tab_url_ref() const { return new_tab_url_ref_; } contextual_search_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_ 703