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.
5 #ifndef COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_H_
6 #define COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_H_
14 #include "base/gtest_prod_util.h"
15 #include "base/macros.h"
16 #include "base/time/time.h"
17 #include "components/search_engines/omnibox_focus_type.h"
18 #include "components/search_engines/search_engine_type.h"
19 #include "components/search_engines/template_url_data.h"
20 #include "components/search_engines/template_url_id.h"
21 #include "third_party/metrics_proto/omnibox_event.pb.h"
22 #include "third_party/metrics_proto/omnibox_input_type.pb.h"
23 #include "ui/gfx/geometry/size.h"
25 #include "url/third_party/mozilla/url_parse.h"
27 class SearchTermsData;
31 // TemplateURLRef -------------------------------------------------------------
33 // A TemplateURLRef represents a single URL within the larger TemplateURL class
34 // (which represents an entire "search engine", see below). If
35 // SupportsReplacement() is true, this URL has placeholders in it, for which
36 // callers can substitute values to get a "real" URL using ReplaceSearchTerms().
38 // TemplateURLRefs always have a non-NULL |owner_| TemplateURL, which they
39 // access in order to get at important data like the underlying URL string or
40 // the associated Profile.
41 class TemplateURLRef {
43 // Magic numbers to pass to ReplaceSearchTerms() for the |accepted_suggestion|
44 // parameter. Most callers aren't using Suggest capabilities and should just
45 // pass NO_SUGGESTIONS_AVAILABLE.
46 // NOTE: Because positive values are meaningful, make sure these are negative!
47 enum AcceptedSuggestion {
48 NO_SUGGESTION_CHOSEN = -1,
49 NO_SUGGESTIONS_AVAILABLE = -2,
52 // Which kind of URL within our owner we are. This allows us to get at the
53 // correct string field. Use |INDEXED| to indicate that the numerical
54 // |index_in_owner_| should be used instead.
64 // Type to store <content_type, post_data> pair for POST URLs.
65 // The |content_type|(first part of the pair) is the content-type of
66 // the |post_data|(second part of the pair) which is encoded in
67 // "multipart/form-data" format, it also contains the MIME boundary used in
68 // the |post_data|. See http://tools.ietf.org/html/rfc2046 for the details.
69 typedef std::pair<std::string, std::string> PostContent;
71 // Enumeration of the known search or suggest request sources. These values
72 // are not persisted or used in histograms; thus can be freely changed.
74 SEARCHBOX, // Omnibox or the NTP realbox. The default.
75 CROS_APP_LIST, // Chrome OS app list search box.
78 // This struct encapsulates arguments passed to
79 // TemplateURLRef::ReplaceSearchTerms methods. By default, only search_terms
80 // is required and is passed in the constructor.
81 struct SearchTermsArgs {
83 explicit SearchTermsArgs(const std::u16string& search_terms);
84 SearchTermsArgs(const SearchTermsArgs& other);
87 struct ContextualSearchParams {
88 ContextualSearchParams();
89 // Modern constructor, used when the content is sent in the HTTP header
90 // instead of as CGI parameters.
91 // The |version| tell the server which version of the client is making
93 // The |contextual_cards_version| tells the server which version of
94 // contextual cards integration is being used by the client.
95 // The |home_country| is an ISO country code for the country that the user
96 // considers their permanent home (which may be different from the country
97 // they are currently visiting). Pass an empty string if none available.
98 // The |previous_event_id| is an identifier previously returned by the
99 // server to identify that user interaction.
100 // The |previous_event_results| are the results of the user-interaction of
101 // that previous request.
102 // The "previous_xyz" parameters are documented in go/cs-sanitized.
103 // The |is_exact_search| allows the search request to be narrowed down to
104 // an "exact" search only, meaning just search for X rather than X +
105 // whatever else is in the context. The returned search term should not
106 // be expanded, and the server will honor this along with creating a
107 // narrow Search Term.
108 // The |source_lang| specifies a source language hint to apply for
109 // translation or to indicate that translation might be appropriate.
110 // This comes from CLD evaluating the selection and/or page content.
111 // The |target_lang| specifies the best language to translate into for
112 // the user, which also indicates when translation is appropriate or
113 // helpful. This comes from the Chrome Language Model.
114 // The |fluent_languages| string specifies the languages the user
115 // is fluent in reading. This acts as an alternate set of languages
116 // to consider translating into. The languages are ordered by
117 // fluency, and encoded as a comma-separated list of BCP 47 languages.
118 // The |related_searches_stamp| string contains an information that
119 // indicates experiment status and server processing results so that
120 // can be logged in GWS Sawmill logs for offline analysis for the
121 // Related Searches MVP experiment.
122 ContextualSearchParams(int version,
123 int contextual_cards_version,
124 std::string home_country,
125 int64_t previous_event_id,
126 int previous_event_results,
127 bool is_exact_search,
128 std::string source_lang,
129 std::string target_lang,
130 std::string fluent_languages,
131 std::string related_searches_stamp);
132 ContextualSearchParams(const ContextualSearchParams& other);
133 ~ContextualSearchParams();
135 // Estimates dynamic memory usage.
136 // See base/trace_event/memory_usage_estimator.h for more info.
137 size_t EstimateMemoryUsage() const;
139 // The version of contextual search.
142 // The version of Contextual Cards data to request.
143 // A value of 0 indicates no data needed.
144 int contextual_cards_version = 0;
146 // The locale of the user's home country in an ISO country code format,
147 // or an empty string if not available. This indicates where the user
148 // resides, not where they currently are.
149 std::string home_country;
151 // An EventID from a previous interaction (sent by server, recorded by
153 int64_t previous_event_id = 0l;
155 // An encoded set of booleans that represent the interaction results from
156 // the previous event.
157 int previous_event_results = 0;
159 // A flag that restricts the search to exactly match the selection rather
160 // than expanding the Search Term to include other words in the context.
161 bool is_exact_search = false;
163 // Source language string to translate from.
164 std::string source_lang;
166 // Target language string to be translated into.
167 std::string target_lang;
169 // Alternate target languages that the user is fluent in, encoded in a
171 std::string fluent_languages;
173 // Experiment arm and processing information for the Related Searches
174 // experiment. The value is an arbitrary string that starts with a
175 // schema version number.
176 std::string related_searches_stamp;
179 // Estimates dynamic memory usage.
180 // See base/trace_event/memory_usage_estimator.h for more info.
181 size_t EstimateMemoryUsage() const;
183 // The search terms (query).
184 std::u16string search_terms;
186 // The original (input) query.
187 std::u16string original_query;
189 // The type the original input query was identified as.
190 metrics::OmniboxInputType input_type = metrics::OmniboxInputType::EMPTY;
192 // Specifies how the user last interacted with the searchbox UI element.
193 OmniboxFocusType focus_type = OmniboxFocusType::DEFAULT;
195 // The optional assisted query stats, aka AQS, used for logging purposes.
196 // This string contains impressions of all autocomplete matches shown
197 // at the query submission time. For privacy reasons, we require the
198 // search provider to support HTTPS protocol in order to receive the AQS
200 // For more details, see http://goto.google.com/binary-clients-logging .
201 std::string assisted_query_stats;
203 // TODO: Remove along with "aq" CGI param.
204 int accepted_suggestion = NO_SUGGESTIONS_AVAILABLE;
206 // The 0-based position of the cursor within the query string at the time
207 // the request was issued. Set to std::u16string::npos if not used.
208 size_t cursor_position = std::u16string::npos;
210 // The URL of the current webpage to be used for experimental zero-prefix
212 std::string current_page_url;
214 // Which omnibox the user used to type the prefix.
215 metrics::OmniboxEventProto::PageClassification page_classification =
216 metrics::OmniboxEventProto::INVALID_SPEC;
218 // Optional session token.
219 std::string session_token;
221 // Prefetch query and type.
222 std::string prefetch_query;
223 std::string prefetch_query_type;
225 // Additional query params to append to the request.
226 std::string additional_query_params;
228 // If set, ReplaceSearchTerms() will automatically append any extra query
229 // params specified via the --extra-search-query-params command-line
230 // argument. Generally, this should be set when dealing with the search
231 // TemplateURLRefs of the default search engine and the caller cares
232 // about the query portion of the URL. Since neither TemplateURLRef nor
233 // indeed TemplateURL know whether a TemplateURL is the default search
234 // engine, callers instead must set this manually.
235 bool append_extra_query_params_from_command_line = false;
237 // The raw content of an image thumbnail that will be used as a query for
238 // search-by-image frontend.
239 std::string image_thumbnail_content;
241 // When searching for an image, the URL of the original image. Callers
242 // should leave this empty for images specified via data: URLs.
245 // When searching for an image, the original size of the image.
246 gfx::Size image_original_size;
248 // Source of the search or suggest request.
249 RequestSource request_source = SEARCHBOX;
251 // Whether the query is being fetched as a prefetch request before the user
252 // actually searches for the search terms.
253 bool is_prefetch = false;
255 ContextualSearchParams contextual_search_params;
258 TemplateURLRef(const TemplateURL* owner, Type type);
259 TemplateURLRef(const TemplateURL* owner, size_t index_in_owner);
262 TemplateURLRef(const TemplateURLRef& source);
263 TemplateURLRef& operator=(const TemplateURLRef& source);
265 // Returns the raw URL. None of the parameters will have been replaced.
266 std::string GetURL() const;
268 // Returns the raw string of the post params. Please see comments in
269 // prepopulated_engines_schema.json for the format.
270 std::string GetPostParamsString() const;
272 // Returns true if this URL supports search term replacement.
273 bool SupportsReplacement(const SearchTermsData& search_terms_data) const;
275 // Returns a string that is the result of replacing the search terms in
276 // the url with the specified arguments. We use our owner's input encoding.
278 // If this TemplateURLRef does not support replacement (SupportsReplacement
279 // returns false), an empty string is returned.
280 // If this TemplateURLRef uses POST, and |post_content| is not NULL, the
281 // |post_params_| will be replaced, encoded in "multipart/form-data" format
282 // and stored into |post_content|.
283 std::string ReplaceSearchTerms(const SearchTermsArgs& search_terms_args,
284 const SearchTermsData& search_terms_data,
285 PostContent* post_content) const;
287 // TODO(jnd): remove the following ReplaceSearchTerms definition which does
288 // not have |post_content| parameter once all reference callers pass
289 // |post_content| parameter.
290 std::string ReplaceSearchTerms(
291 const SearchTermsArgs& search_terms_args,
292 const SearchTermsData& search_terms_data) const {
293 return ReplaceSearchTerms(search_terms_args, search_terms_data, NULL);
296 // Returns true if the TemplateURLRef is valid. An invalid TemplateURLRef is
297 // one that contains unknown terms, or invalid characters.
298 bool IsValid(const SearchTermsData& search_terms_data) const;
300 // Returns a string representation of this TemplateURLRef suitable for
301 // display. The display format is the same as the format used by Firefox.
302 std::u16string DisplayURL(const SearchTermsData& search_terms_data) const;
304 // Converts a string as returned by DisplayURL back into a string as
305 // understood by TemplateURLRef.
306 static std::string DisplayURLToURLRef(const std::u16string& display_url);
308 // If this TemplateURLRef is valid and contains one search term, this returns
309 // the host/path of the URL, otherwise this returns an empty string.
310 const std::string& GetHost(const SearchTermsData& search_terms_data) const;
311 std::string GetPath(const SearchTermsData& search_terms_data) const;
313 // If this TemplateURLRef is valid and contains one search term
314 // in its query or ref, this returns the key of the search term,
315 // otherwise this returns an empty string.
316 const std::string& GetSearchTermKey(
317 const SearchTermsData& search_terms_data) const;
319 // If this TemplateURLRef is valid and contains one search term,
320 // this returns the location of the search term,
321 // otherwise this returns url::Parsed::QUERY.
322 url::Parsed::ComponentType GetSearchTermKeyLocation(
323 const SearchTermsData& search_terms_data) const;
325 // If this TemplateURLRef is valid and contains one search term,
326 // this returns the fixed prefix before the search term,
327 // otherwise this returns an empty string.
328 const std::string& GetSearchTermValuePrefix(
329 const SearchTermsData& search_terms_data) const;
331 // If this TemplateURLRef is valid and contains one search term,
332 // this returns the fixed suffix after the search term,
333 // otherwise this returns an empty string.
334 const std::string& GetSearchTermValueSuffix(
335 const SearchTermsData& search_terms_data) const;
337 // Converts the specified term in our owner's encoding to a std::u16string.
338 std::u16string SearchTermToString16(const base::StringPiece& term) const;
340 // Returns true if this TemplateURLRef has a replacement term of
341 // {google:baseURL} or {google:baseSuggestURL}.
342 bool HasGoogleBaseURLs(const SearchTermsData& search_terms_data) const;
344 // Use the pattern referred to by this TemplateURLRef to match the provided
345 // |url| and extract |search_terms| from it. Returns true if the pattern
346 // matches, even if |search_terms| is empty. In this case
347 // |search_term_component|, if not NULL, indicates whether the search terms
348 // were found in the query or the ref parameters; and |search_terms_position|,
349 // if not NULL, contains the position of the search terms in the query or the
350 // ref parameters. Returns false and an empty |search_terms| if the pattern
352 bool ExtractSearchTermsFromURL(
354 std::u16string* search_terms,
355 const SearchTermsData& search_terms_data,
356 url::Parsed::ComponentType* search_term_component,
357 url::Component* search_terms_position) const;
359 // Whether the URL uses POST (as opposed to GET).
360 bool UsesPOSTMethod(const SearchTermsData& search_terms_data) const;
362 // Estimates dynamic memory usage.
363 // See base/trace_event/memory_usage_estimator.h for more info.
364 size_t EstimateMemoryUsage() const;
367 friend class TemplateURL;
368 friend class TemplateURLTest;
369 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, SetPrepopulatedAndParse);
370 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterKnown);
371 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseParameterUnknown);
372 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLEmpty);
373 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoTemplateEnd);
374 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNoKnownParameters);
375 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLTwoParameters);
376 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, ParseURLNestedParameter);
377 FRIEND_TEST_ALL_PREFIXES(TemplateURLTest, URLRefTestImageURLWithPOST);
379 // Enumeration of the known types.
380 enum ReplacementType {
382 GOOGLE_ASSISTED_QUERY_STATS,
384 GOOGLE_BASE_SEARCH_BY_IMAGE_URL,
385 GOOGLE_BASE_SUGGEST_URL,
386 GOOGLE_CONTEXTUAL_SEARCH_VERSION,
387 GOOGLE_CONTEXTUAL_SEARCH_CONTEXT_DATA,
388 GOOGLE_CURRENT_PAGE_URL,
389 GOOGLE_CURSOR_POSITION,
390 GOOGLE_IMAGE_ORIGINAL_HEIGHT,
391 GOOGLE_IMAGE_ORIGINAL_WIDTH,
392 GOOGLE_IMAGE_SEARCH_SOURCE,
393 GOOGLE_IMAGE_THUMBNAIL,
394 GOOGLE_IMAGE_THUMBNAIL_BASE64,
397 GOOGLE_IOS_SEARCH_LANGUAGE,
398 GOOGLE_NTP_IS_THEMED,
399 GOOGLE_OMNIBOX_FOCUS_TYPE,
400 GOOGLE_ORIGINAL_QUERY_FOR_SUGGESTION,
401 GOOGLE_PAGE_CLASSIFICATION,
402 GOOGLE_PREFETCH_QUERY,
403 GOOGLE_PREFETCH_SOURCE,
405 GOOGLE_SEARCH_CLIENT,
406 GOOGLE_SEARCH_FIELDTRIAL_GROUP,
407 GOOGLE_SEARCH_VERSION,
408 GOOGLE_SESSION_TOKEN,
409 GOOGLE_SUGGEST_CLIENT,
410 GOOGLE_SUGGEST_REQUEST_ID,
411 GOOGLE_UNESCAPED_SEARCH_TERMS,
418 // Used to identify an element of the raw url that can be replaced.
420 Replacement(ReplacementType type, size_t index)
421 : type(type), index(index), is_post_param(false) {}
422 ReplacementType type;
424 // Indicates the location in where the replacement is replaced. If
425 // |is_post_param| is false, |index| indicates the byte position in
426 // |parsed_url_|. Otherwise, |index| is the index of |post_params_|.
430 // Stores a single parameter for a POST.
434 std::string content_type;
436 // Estimates dynamic memory usage.
437 // See base/trace_event/memory_usage_estimator.h for more info.
438 size_t EstimateMemoryUsage() const;
441 // The list of elements to replace.
442 typedef std::vector<struct Replacement> Replacements;
443 typedef std::vector<PostParam> PostParams;
445 // TemplateURLRef internally caches values to make replacement quick. This
446 // method invalidates any cached values.
447 void InvalidateCachedValues() const;
449 // Parses the parameter in url at the specified offset. start/end specify the
450 // range of the parameter in the url, including the braces. If the parameter
451 // is valid, url is updated to reflect the appropriate parameter. If
452 // the parameter is one of the known parameters an element is added to
453 // replacements indicating the type and range of the element. The original
454 // parameter is erased from the url.
456 // If the parameter is not a known parameter, false is returned. If this is a
457 // prepopulated URL, the parameter is erased, otherwise it is left alone.
458 bool ParseParameter(size_t start,
461 Replacements* replacements) const;
463 // Parses the specified url, replacing parameters as necessary. If
464 // successful, valid is set to true, and the parsed url is returned. For all
465 // known parameters that are encountered an entry is added to replacements.
466 // If there is an error parsing the url, valid is set to false, and an empty
467 // string is returned. If the URL has the POST parameters, they will be
468 // parsed into |post_params| which will be further replaced with real search
469 // terms data and encoded in "multipart/form-data" format to generate the
471 std::string ParseURL(const std::string& url,
472 Replacements* replacements,
473 PostParams* post_params,
476 // If the url has not yet been parsed, ParseURL is invoked.
477 // NOTE: While this is const, it modifies parsed_, valid_, parsed_url_ and
479 void ParseIfNecessary(const SearchTermsData& search_terms_data) const;
481 // Parses a wildcard out of |path|, putting the parsed path in |path_prefix_|
482 // and |path_suffix_| and setting |path_wildcard_present_| to true.
483 // In the absence of a wildcard, the full path will be contained in
484 // |path_prefix_| and |path_wildcard_present_| will be false.
485 void ParsePath(const std::string& path) const;
487 // Returns whether the path portion of this template URL is equal to the path
488 // in |url|, checking that URL is prefixed/suffixed by
489 // |path_prefix_|/|path_suffix_| if |path_wildcard_present_| is true, or equal
490 // to |path_prefix_| otherwise.
491 bool PathIsEqual(const GURL& url) const;
493 // Extracts the query key and host from the url.
494 void ParseHostAndSearchTermKey(
495 const SearchTermsData& search_terms_data) const;
497 // Encode post parameters in "multipart/form-data" format and store it
498 // inside |post_content|. Returns false if errors are encountered during
499 // encoding. This method is called each time ReplaceSearchTerms gets called.
500 bool EncodeFormData(const PostParams& post_params,
501 PostContent* post_content) const;
503 // Handles a replacement by using real term data. If the replacement
504 // belongs to a PostParam, the PostParam will be replaced by the term data.
505 // Otherwise, the term data will be inserted at the place that the
506 // replacement points to.
507 void HandleReplacement(const std::string& name,
508 const std::string& value,
509 const Replacement& replacement,
510 std::string* url) const;
512 // Replaces all replacements in |parsed_url_| with their actual values and
513 // returns the result. This is the main functionality of
514 // ReplaceSearchTerms().
515 std::string HandleReplacements(
516 const SearchTermsArgs& search_terms_args,
517 const SearchTermsData& search_terms_data,
518 PostContent* post_content) const;
520 // The TemplateURL that contains us. This should outlive us.
521 const TemplateURL* owner_;
523 // What kind of URL we are.
526 // If |type_| is |INDEXED|, this |index_in_owner_| is used instead to refer to
527 // a url within our owner.
528 size_t index_in_owner_ = 0;
530 // Whether the URL has been parsed.
531 mutable bool parsed_ = false;
533 // Whether the url was successfully parsed.
534 mutable bool valid_ = false;
536 // The parsed URL. All terms have been stripped out of this with
537 // replacements_ giving the index of the terms to replace.
538 mutable std::string parsed_url_;
540 // Do we support search term replacement?
541 mutable bool supports_replacements_ = false;
543 // The replaceable parts of url (parsed_url_). These are ordered by index
544 // into the string, and may be empty.
545 mutable Replacements replacements_;
547 // Whether the path contains a wildcard.
548 mutable bool path_wildcard_present_ = false;
550 // Host, port, path, key and location of the search term. These are only set
551 // if the url contains one search term.
552 mutable std::string host_;
553 mutable std::string port_;
554 mutable std::string path_prefix_;
555 mutable std::string path_suffix_;
556 mutable std::string search_term_key_;
557 mutable url::Parsed::ComponentType search_term_key_location_ =
559 mutable std::string search_term_value_prefix_;
560 mutable std::string search_term_value_suffix_;
562 mutable PostParams post_params_;
564 // Whether the contained URL is a pre-populated URL.
565 bool prepopulated_ = false;
569 // TemplateURL ----------------------------------------------------------------
571 // A TemplateURL represents a single "search engine", defined primarily as a
572 // subset of the Open Search Description Document
573 // (http://www.opensearch.org/Specifications/OpenSearch) plus some extensions.
574 // One TemplateURL contains several TemplateURLRefs, which correspond to various
575 // different capabilities (e.g. doing searches or getting suggestions), as well
576 // as a TemplateURLData containing other details like the name, keyword, etc.
578 // TemplateURLs are intended to be read-only for most users.
579 // The TemplateURLService, which handles storing and manipulating TemplateURLs,
580 // is made a friend so that it can be the exception to this pattern.
583 using TemplateURLVector = std::vector<TemplateURL*>;
584 using OwnedTemplateURLVector = std::vector<std::unique_ptr<TemplateURL>>;
586 // These values are not persisted and can be freely changed.
587 // Their integer values are used for choosing the best engine during keyword
588 // conflicts, so their relative ordering should not be changed without careful
589 // thought about what happens during version skew.
591 // Installed only on this device. Should not be synced. This is not common.
593 // Regular search engine. This is the most common, and the ONLY type synced.
595 // Installed by extension through Override Settings API. Not synced.
596 NORMAL_CONTROLLED_BY_EXTENSION = 2,
597 // The keyword associated with an extension that uses the Omnibox API.
599 OMNIBOX_API_EXTENSION = 3,
602 // An AssociatedExtensionInfo represents information about the extension that
603 // added the search engine.
604 struct AssociatedExtensionInfo {
605 AssociatedExtensionInfo(const std::string& extension_id,
606 base::Time install_time,
607 bool wants_to_be_default_engine);
608 ~AssociatedExtensionInfo();
610 // Estimates dynamic memory usage.
611 // See base/trace_event/memory_usage_estimator.h for more info.
612 size_t EstimateMemoryUsage() const;
614 std::string extension_id;
616 // Used to resolve conflicts when there are multiple extensions specifying
617 // the default search engine. The most recently-installed wins.
618 base::Time install_time;
620 // Whether the search engine is supposed to be default.
621 bool wants_to_be_default_engine;
624 explicit TemplateURL(const TemplateURLData& data, Type type = NORMAL);
626 // Constructor for extension controlled engine. |type| must be
627 // NORMAL_CONTROLLED_BY_EXTENSION or OMNIBOX_API_EXTENSION.
628 TemplateURL(const TemplateURLData& data,
630 std::string extension_id,
631 base::Time install_time,
632 bool wants_to_be_default_engine);
636 // For two engines with the same keyword, |this| and |other|,
637 // returns true if |this| is strictly better than |other|.
639 // While normal engines must all have distinct keywords, policy-created,
640 // extension-controlled and omnibox API engines may have the same keywords as
641 // each other or as normal engines. In these cases, policy-create engines
642 // override omnibox API engines, which override extension-controlled engines,
643 // which override normal engines.
645 // If there is still a conflict after this, compare by safe-for-autoreplace,
646 // then last modified date, then use the sync guid as a tiebreaker.
648 // TODO(tommycli): I'd like to use this to resolve Sync conflicts in the
649 // future, but we need a total ordering of TemplateURLs. That's not the case
650 // today, because the sync GUIDs are not actually globally unique, so there
651 // can be a genuine tie, which is not good, because then two different clients
652 // could choose to resolve the conflict in two different ways.
653 bool IsBetterThanEngineWithConflictingKeyword(const TemplateURL* other) const;
655 // Generates a suitable keyword for the specified url, which must be valid.
656 // This is guaranteed not to return an empty string, since TemplateURLs should
657 // never have an empty keyword.
658 static std::u16string GenerateKeyword(const GURL& url);
660 // Generates a favicon URL from the specified url.
661 static GURL GenerateFaviconURL(const GURL& url);
663 // Returns true if |t_url| and |data| are equal in all meaningful respects.
664 // Static to allow either or both params to be NULL.
665 static bool MatchesData(const TemplateURL* t_url,
666 const TemplateURLData* data,
667 const SearchTermsData& search_terms_data);
669 const TemplateURLData& data() const { return data_; }
671 const std::u16string& short_name() const { return data_.short_name(); }
672 // An accessor for the short_name, but adjusted so it can be appropriately
673 // displayed even if it is LTR and the UI is RTL.
674 std::u16string AdjustedShortNameForLocaleDirection() const;
676 const std::u16string& keyword() const { return data_.keyword(); }
678 const std::string& url() const { return data_.url(); }
679 const std::string& suggestions_url() const { return data_.suggestions_url; }
680 const std::string& image_url() const { return data_.image_url; }
681 const std::string& new_tab_url() const { return data_.new_tab_url; }
682 const std::string& contextual_search_url() const {
683 return data_.contextual_search_url;
685 const std::string& search_url_post_params() const {
686 return data_.search_url_post_params;
688 const std::string& suggestions_url_post_params() const {
689 return data_.suggestions_url_post_params;
691 const std::string& image_url_post_params() const {
692 return data_.image_url_post_params;
694 const std::vector<std::string>& alternate_urls() const {
695 return data_.alternate_urls;
697 const GURL& favicon_url() const { return data_.favicon_url; }
699 const GURL& logo_url() const { return data_.logo_url; }
701 const GURL& doodle_url() const { return data_.doodle_url; }
703 const GURL& originating_url() const { return data_.originating_url; }
705 bool safe_for_autoreplace() const { return data_.safe_for_autoreplace; }
707 const std::vector<std::string>& input_encodings() const {
708 return data_.input_encodings;
711 TemplateURLID id() const { return data_.id; }
713 base::Time date_created() const { return data_.date_created; }
714 base::Time last_modified() const { return data_.last_modified; }
715 base::Time last_visited() const { return data_.last_visited; }
717 bool created_by_policy() const { return data_.created_by_policy; }
718 bool created_from_play_api() const { return data_.created_from_play_api; }
720 int usage_count() const { return data_.usage_count; }
722 int prepopulate_id() const { return data_.prepopulate_id; }
724 const std::string& sync_guid() const { return data_.sync_guid; }
726 TemplateURLData::ActiveStatus is_active() const { return data_.is_active; }
728 const std::vector<TemplateURLRef>& url_refs() const { return url_refs_; }
729 const TemplateURLRef& url_ref() const {
730 // Sanity check for https://crbug.com/781703.
731 CHECK(!url_refs_.empty());
732 return url_refs_.back();
734 const TemplateURLRef& suggestions_url_ref() const {
735 return suggestions_url_ref_;
737 const TemplateURLRef& image_url_ref() const { return image_url_ref_; }
738 const TemplateURLRef& new_tab_url_ref() const { return new_tab_url_ref_; }
739 const TemplateURLRef& contextual_search_url_ref() const {
740 return contextual_search_url_ref_;
743 Type type() const { return type_; }
745 const AssociatedExtensionInfo* GetExtensionInfoForTesting() const {
746 return extension_info_.get();
749 // Returns true if |url| supports replacement.
750 bool SupportsReplacement(const SearchTermsData& search_terms_data) const;
752 // Returns true if any URLRefs use Googe base URLs.
753 bool HasGoogleBaseURLs(const SearchTermsData& search_terms_data) const;
755 // Returns true if this TemplateURL uses Google base URLs and has a keyword
756 // of "google.TLD". We use this to decide whether we can automatically
757 // update the keyword to reflect the current Google base URL TLD.
758 bool IsGoogleSearchURLWithReplaceableKeyword(
759 const SearchTermsData& search_terms_data) const;
761 // Returns true if the keywords match or if
762 // IsGoogleSearchURLWithReplaceableKeyword() is true for both |this| and
764 bool HasSameKeywordAs(const TemplateURLData& other,
765 const SearchTermsData& search_terms_data) const;
767 // Returns the id of the extension that added this search engine. Only call
768 // this for TemplateURLs of type NORMAL_CONTROLLED_BY_EXTENSION or
769 // OMNIBOX_API_EXTENSION.
770 std::string GetExtensionId() const;
772 // Returns the type of this search engine, or SEARCH_ENGINE_OTHER if no
774 SearchEngineType GetEngineType(
775 const SearchTermsData& search_terms_data) const;
777 // Use the alternate URLs and the search URL to match the provided |url|
778 // and extract |search_terms| from it. Returns false and an empty
779 // |search_terms| if no search terms can be matched. The URLs are matched in
780 // the order listed in |url_refs_| (see comment there).
781 bool ExtractSearchTermsFromURL(const GURL& url,
782 const SearchTermsData& search_terms_data,
783 std::u16string* search_terms) const;
785 // Returns true if non-empty search terms could be extracted from |url| using
786 // ExtractSearchTermsFromURL(). In other words, this returns whether |url|
787 // could be the result of performing a search with |this|.
788 bool IsSearchURL(const GURL& url,
789 const SearchTermsData& search_terms_data) const;
791 // Given a |url| corresponding to this TemplateURL, identifies the search
792 // terms and replaces them with the ones in |search_terms_args|, leaving the
793 // other parameters untouched. If the replacement fails, returns false and
794 // leaves |result| untouched. This is used by mobile ports to perform query
796 bool ReplaceSearchTermsInURL(
798 const TemplateURLRef::SearchTermsArgs& search_terms_args,
799 const SearchTermsData& search_terms_data,
802 // Encodes the search terms from |search_terms_args| so that we know the
803 // |input_encoding|. Returns the |encoded_terms| and the
804 // |encoded_original_query|. |encoded_terms| may be escaped as path or query
805 // depending on |is_in_query|; |encoded_original_query| is always escaped as
807 void EncodeSearchTerms(
808 const TemplateURLRef::SearchTermsArgs& search_terms_args,
810 std::string* input_encoding,
811 std::u16string* encoded_terms,
812 std::u16string* encoded_original_query) const;
814 // Returns the search url for this template URL.
815 // Returns an empty GURL if this template URL has no url().
816 GURL GenerateSearchURL(const SearchTermsData& search_terms_data) const;
818 // TemplateURL internally caches values derived from a passed SearchTermsData
819 // to make its functions quick. This method invalidates any cached values and
820 // it should be called after SearchTermsData has been changed.
821 void InvalidateCachedValues() const;
823 // Estimates dynamic memory usage.
824 // See base/trace_event/memory_usage_estimator.h for more info.
825 size_t EstimateMemoryUsage() const;
828 friend class TemplateURLService;
830 void CopyFrom(const TemplateURL& other);
832 void SetURL(const std::string& url);
833 void SetPrepopulateId(int id);
835 // Resets the keyword if IsGoogleSearchURLWithReplaceableKeyword() or |force|.
836 // The |force| parameter is useful when the existing keyword is known to be
837 // a placeholder. The resulting keyword is generated using
838 // GenerateSearchURL() and GenerateKeyword().
839 void ResetKeywordIfNecessary(const SearchTermsData& search_terms_data,
842 // Resizes the |url_refs_| vector, which always holds the search URL as the
844 void ResizeURLRefVector();
846 // Uses the alternate URLs and the search URL to match the provided |url|
847 // and extract |search_terms| from it as well as the |search_terms_component|
848 // (either REF or QUERY) and |search_terms_component| at which the
849 // |search_terms| are found in |url|. See also ExtractSearchTermsFromURL().
850 bool FindSearchTermsInURL(const GURL& url,
851 const SearchTermsData& search_terms_data,
852 std::u16string* search_terms,
853 url::Parsed::ComponentType* search_terms_component,
854 url::Component* search_terms_position) const;
856 TemplateURLData data_;
858 // Contains TemplateURLRefs corresponding to the alternate URLs and the search
859 // URL, in priority order: the URL at index 0 is treated as the highest
860 // priority and the primary search URL is treated as the lowest priority. For
861 // example, if a TemplateURL has alternate URL "http://foo/#q={searchTerms}"
862 // and search URL "http://foo/?q={searchTerms}", and the URL to be decoded is
863 // "http://foo/?q=a#q=b", the alternate URL will match first and the decoded
864 // search term will be "b". Note that since every TemplateURLRef has a
865 // primary search URL, this vector is never empty.
866 std::vector<TemplateURLRef> url_refs_;
868 TemplateURLRef suggestions_url_ref_;
869 TemplateURLRef image_url_ref_;
870 TemplateURLRef new_tab_url_ref_;
871 TemplateURLRef contextual_search_url_ref_;
872 std::unique_ptr<AssociatedExtensionInfo> extension_info_;
876 // Caches the computed engine type across successive calls to GetEngineType().
877 mutable SearchEngineType engine_type_;
879 // TODO(sky): Add date last parsed OSD file.
881 DISALLOW_COPY_AND_ASSIGN(TemplateURL);
884 #endif // COMPONENTS_SEARCH_ENGINES_TEMPLATE_URL_H_