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