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