| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/search_engines/template_url.h" | 5 #include "chrome/browser/search_engines/template_url.h" |
| 6 | 6 |
| 7 #include "base/i18n/case_conversion.h" | 7 #include "base/i18n/case_conversion.h" |
| 8 #include "base/i18n/icu_string_conversions.h" | 8 #include "base/i18n/icu_string_conversions.h" |
| 9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/metrics/field_trial.h" | 11 #include "base/metrics/field_trial.h" |
| 12 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
| 13 #include "base/stringprintf.h" | 13 #include "base/stringprintf.h" |
| 14 #include "base/utf_string_conversions.h" | 14 #include "base/utf_string_conversions.h" |
| 15 #include "chrome/browser/autocomplete/autocomplete_field_trial.h" | 15 #include "chrome/browser/autocomplete/autocomplete_field_trial.h" |
| 16 #include "chrome/browser/google/google_util.h" | 16 #include "chrome/browser/google/google_util.h" |
| 17 #include "chrome/browser/search_engines/search_terms_data.h" | 17 #include "chrome/browser/search_engines/search_terms_data.h" |
| 18 #include "chrome/browser/search_engines/template_url_service.h" | 18 #include "chrome/browser/search_engines/template_url_service.h" |
| 19 #include "chrome/common/guid.h" | 19 #include "chrome/common/guid.h" |
| 20 #include "chrome/common/url_constants.h" | 20 #include "chrome/common/url_constants.h" |
| 21 #include "content/public/browser/user_metrics.h" | 21 #include "content/public/browser/user_metrics.h" |
| 22 #include "net/base/escape.h" | 22 #include "net/base/escape.h" |
| 23 #include "ui/base/l10n/l10n_util.h" | 23 #include "ui/base/l10n/l10n_util.h" |
| 24 | 24 |
| 25 using content::UserMetricsAction; | |
| 26 | |
| 27 // TODO(pastarmovj): Remove google_update_settings and user_metrics when the | 25 // TODO(pastarmovj): Remove google_update_settings and user_metrics when the |
| 28 // CollectRLZMetrics function is not needed anymore. | 26 // CollectRLZMetrics function is not needed anymore. |
| 29 | 27 |
| 30 // The TemplateURLRef has any number of terms that need to be replaced. Each of | 28 // The TemplateURLRef has any number of terms that need to be replaced. Each of |
| 31 // the terms is enclosed in braces. If the character preceeding the final | 29 // the terms is enclosed in braces. If the character preceeding the final |
| 32 // brace is a ?, it indicates the term is optional and can be replaced with | 30 // brace is a ?, it indicates the term is optional and can be replaced with |
| 33 // an empty string. | 31 // an empty string. |
| 34 static const char kStartParameter = '{'; | 32 static const char kStartParameter = '{'; |
| 35 static const char kEndParameter = '}'; | 33 static const char kEndParameter = '}'; |
| 36 static const char kOptional = '?'; | 34 static const char kOptional = '?'; |
| (...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 search_term_key_ = query_string.substr(key.begin, key.len); | 559 search_term_key_ = query_string.substr(key.begin, key.len); |
| 562 host_ = url.host(); | 560 host_ = url.host(); |
| 563 path_ = url.path(); | 561 path_ = url.path(); |
| 564 break; | 562 break; |
| 565 } | 563 } |
| 566 } | 564 } |
| 567 } | 565 } |
| 568 } | 566 } |
| 569 | 567 |
| 570 | 568 |
| 569 // TemplateURLData ------------------------------------------------------------ |
| 570 |
| 571 TemplateURLData::TemplateURLData() |
| 572 : show_in_default_list(false), |
| 573 safe_for_autoreplace(false), |
| 574 id(0), |
| 575 date_created(base::Time::Now()), |
| 576 last_modified(base::Time::Now()), |
| 577 created_by_policy(false), |
| 578 usage_count(0), |
| 579 prepopulate_id(0), |
| 580 sync_guid(guid::GenerateGUID()), |
| 581 autogenerate_keyword_(false), |
| 582 keyword_generated_(false) { |
| 583 } |
| 584 |
| 585 void TemplateURLData::SetKeyword(const string16& keyword) const { |
| 586 // Case sensitive keyword matching is confusing. As such, we force all |
| 587 // keywords to be lower case. |
| 588 keyword_ = base::i18n::ToLower(keyword); |
| 589 autogenerate_keyword_ = false; |
| 590 } |
| 591 |
| 592 const string16& TemplateURLData::keyword(const TemplateURL* t_url) const { |
| 593 EnsureKeyword(t_url); |
| 594 return keyword_; |
| 595 } |
| 596 |
| 597 void TemplateURLData::SetAutogenerateKeyword(bool autogenerate_keyword) const { |
| 598 autogenerate_keyword_ = autogenerate_keyword; |
| 599 if (autogenerate_keyword_) { |
| 600 keyword_.clear(); |
| 601 keyword_generated_ = false; |
| 602 } |
| 603 } |
| 604 |
| 605 void TemplateURLData::EnsureKeyword(const TemplateURL* t_url) const { |
| 606 if (autogenerate_keyword_ && !keyword_generated_) { |
| 607 // Generate a keyword and cache it. |
| 608 keyword_ = base::i18n::ToLower(TemplateURLService::GenerateKeyword( |
| 609 TemplateURLService::GenerateSearchURL(t_url).GetWithEmptyPath(), true)); |
| 610 keyword_generated_ = true; |
| 611 } |
| 612 } |
| 613 |
| 614 void TemplateURLData::SetURL(const std::string& url) { |
| 615 url_ = url; |
| 616 } |
| 617 |
| 618 |
| 571 // TemplateURL ---------------------------------------------------------------- | 619 // TemplateURL ---------------------------------------------------------------- |
| 572 | 620 |
| 573 TemplateURL::TemplateURL() | 621 TemplateURL::TemplateURL(const TemplateURLData& data) |
| 574 : autogenerate_keyword_(false), | 622 : data_(data), |
| 575 keyword_generated_(false), | |
| 576 show_in_default_list_(false), | |
| 577 safe_for_autoreplace_(false), | |
| 578 id_(0), | |
| 579 date_created_(base::Time::Now()), | |
| 580 last_modified_(base::Time::Now()), | |
| 581 created_by_policy_(false), | |
| 582 usage_count_(0), | |
| 583 prepopulate_id_(0), | |
| 584 sync_guid_(guid::GenerateGUID()), | |
| 585 url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), TemplateURLRef::SEARCH), | 623 url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), TemplateURLRef::SEARCH), |
| 586 suggestions_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 624 suggestions_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 587 TemplateURLRef::SUGGEST), | 625 TemplateURLRef::SUGGEST), |
| 588 instant_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 626 instant_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 589 TemplateURLRef::INSTANT) { | 627 TemplateURLRef::INSTANT) { |
| 628 SetPrepopulateId(data_.prepopulate_id); |
| 590 } | 629 } |
| 591 | 630 |
| 592 TemplateURL::TemplateURL(const TemplateURL& other) | 631 TemplateURL::TemplateURL(const TemplateURL& other) |
| 593 : short_name_(other.short_name_), | 632 : data_(other.data_), |
| 594 url_(other.url_), | |
| 595 suggestions_url_(other.suggestions_url_), | |
| 596 instant_url_(other.instant_url_), | |
| 597 originating_url_(other.originating_url_), | |
| 598 keyword_(other.keyword_), | |
| 599 autogenerate_keyword_(other.autogenerate_keyword_), | |
| 600 keyword_generated_(other.keyword_generated_), | |
| 601 show_in_default_list_(other.show_in_default_list_), | |
| 602 safe_for_autoreplace_(other.safe_for_autoreplace_), | |
| 603 favicon_url_(other.favicon_url_), | |
| 604 input_encodings_(other.input_encodings_), | |
| 605 id_(other.id_), | |
| 606 date_created_(other.date_created_), | |
| 607 last_modified_(other.last_modified_), | |
| 608 created_by_policy_(other.created_by_policy_), | |
| 609 usage_count_(other.usage_count_), | |
| 610 sync_guid_(other.sync_guid_), | |
| 611 url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), TemplateURLRef::SEARCH), | 633 url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), TemplateURLRef::SEARCH), |
| 612 suggestions_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 634 suggestions_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 613 TemplateURLRef::SUGGEST), | 635 TemplateURLRef::SUGGEST), |
| 614 instant_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), | 636 instant_url_ref_(ALLOW_THIS_IN_INITIALIZER_LIST(this), |
| 615 TemplateURLRef::INSTANT) { | 637 TemplateURLRef::INSTANT) { |
| 616 CopyURLRefs(other); | 638 SetPrepopulateId(data_.prepopulate_id); |
| 617 } | 639 } |
| 618 | 640 |
| 619 TemplateURL& TemplateURL::operator=(const TemplateURL& other) { | 641 TemplateURL& TemplateURL::operator=(const TemplateURL& other) { |
| 620 if (this == &other) | 642 if (this == &other) |
| 621 return *this; | 643 return *this; |
| 622 | 644 |
| 623 short_name_ = other.short_name_; | 645 data_ = other.data_; |
| 624 url_ = other.url_; | 646 url_ref_.InvalidateCachedValues(); |
| 625 suggestions_url_ = other.suggestions_url_; | 647 suggestions_url_ref_.InvalidateCachedValues(); |
| 626 instant_url_ = other.instant_url_; | 648 instant_url_ref_.InvalidateCachedValues(); |
| 627 originating_url_ = other.originating_url_; | 649 SetPrepopulateId(data_.prepopulate_id); |
| 628 keyword_ = other.keyword_; | |
| 629 autogenerate_keyword_ = other.autogenerate_keyword_; | |
| 630 keyword_generated_ = other.keyword_generated_; | |
| 631 show_in_default_list_ = other.show_in_default_list_; | |
| 632 safe_for_autoreplace_ = other.safe_for_autoreplace_; | |
| 633 favicon_url_ = other.favicon_url_; | |
| 634 input_encodings_ = other.input_encodings_; | |
| 635 id_ = other.id_; | |
| 636 date_created_ = other.date_created_; | |
| 637 last_modified_ = other.last_modified_; | |
| 638 created_by_policy_ = other.created_by_policy_; | |
| 639 usage_count_ = other.usage_count_; | |
| 640 sync_guid_ = other.sync_guid_; | |
| 641 CopyURLRefs(other); | |
| 642 return *this; | 650 return *this; |
| 643 } | 651 } |
| 644 | 652 |
| 645 TemplateURL::~TemplateURL() { | 653 TemplateURL::~TemplateURL() { |
| 646 } | 654 } |
| 647 | 655 |
| 648 // static | 656 // static |
| 649 GURL TemplateURL::GenerateFaviconURL(const GURL& url) { | 657 GURL TemplateURL::GenerateFaviconURL(const GURL& url) { |
| 650 DCHECK(url.is_valid()); | 658 DCHECK(url.is_valid()); |
| 651 GURL::Replacements rep; | 659 GURL::Replacements rep; |
| 652 | 660 |
| 653 const char favicon_path[] = "/favicon.ico"; | 661 const char favicon_path[] = "/favicon.ico"; |
| 654 int favicon_path_len = arraysize(favicon_path) - 1; | 662 int favicon_path_len = arraysize(favicon_path) - 1; |
| 655 | 663 |
| 656 rep.SetPath(favicon_path, url_parse::Component(0, favicon_path_len)); | 664 rep.SetPath(favicon_path, url_parse::Component(0, favicon_path_len)); |
| 657 rep.ClearUsername(); | 665 rep.ClearUsername(); |
| 658 rep.ClearPassword(); | 666 rep.ClearPassword(); |
| 659 rep.ClearQuery(); | 667 rep.ClearQuery(); |
| 660 rep.ClearRef(); | 668 rep.ClearRef(); |
| 661 return url.ReplaceComponents(rep); | 669 return url.ReplaceComponents(rep); |
| 662 } | 670 } |
| 663 | 671 |
| 664 string16 TemplateURL::AdjustedShortNameForLocaleDirection() const { | 672 string16 TemplateURL::AdjustedShortNameForLocaleDirection() const { |
| 665 string16 bidi_safe_short_name = short_name_; | 673 string16 bidi_safe_short_name = data_.short_name; |
| 666 base::i18n::AdjustStringForLocaleDirection(&bidi_safe_short_name); | 674 base::i18n::AdjustStringForLocaleDirection(&bidi_safe_short_name); |
| 667 return bidi_safe_short_name; | 675 return bidi_safe_short_name; |
| 668 } | 676 } |
| 669 | 677 |
| 678 bool TemplateURL::ShowInDefaultList() const { |
| 679 return data_.show_in_default_list && url_ref_.SupportsReplacement(); |
| 680 } |
| 681 |
| 682 bool TemplateURL::SupportsReplacement() const { |
| 683 UIThreadSearchTermsData search_terms_data; |
| 684 return SupportsReplacementUsingTermsData(search_terms_data); |
| 685 } |
| 686 |
| 687 bool TemplateURL::SupportsReplacementUsingTermsData( |
| 688 const SearchTermsData& search_terms_data) const { |
| 689 return url_ref_.SupportsReplacementUsingTermsData(search_terms_data); |
| 690 } |
| 691 |
| 692 std::string TemplateURL::GetExtensionId() const { |
| 693 DCHECK(IsExtensionKeyword()); |
| 694 return GURL(data_.url()).host(); |
| 695 } |
| 696 |
| 697 bool TemplateURL::IsExtensionKeyword() const { |
| 698 return GURL(data_.url()).SchemeIs(chrome::kExtensionScheme); |
| 699 } |
| 700 |
| 670 void TemplateURL::SetURL(const std::string& url) { | 701 void TemplateURL::SetURL(const std::string& url) { |
| 671 url_ = url; | 702 data_.SetURL(url); |
| 672 url_ref_.InvalidateCachedValues(); | 703 url_ref_.InvalidateCachedValues(); |
| 673 } | 704 } |
| 674 | 705 |
| 675 void TemplateURL::SetSuggestionsURL(const std::string& url) { | |
| 676 suggestions_url_ = url; | |
| 677 suggestions_url_ref_.InvalidateCachedValues(); | |
| 678 } | |
| 679 | |
| 680 void TemplateURL::SetInstantURL(const std::string& url) { | |
| 681 instant_url_ = url; | |
| 682 instant_url_ref_.InvalidateCachedValues(); | |
| 683 } | |
| 684 | |
| 685 void TemplateURL::set_keyword(const string16& keyword) { | |
| 686 // Case sensitive keyword matching is confusing. As such, we force all | |
| 687 // keywords to be lower case. | |
| 688 keyword_ = base::i18n::ToLower(keyword); | |
| 689 autogenerate_keyword_ = false; | |
| 690 } | |
| 691 | |
| 692 const string16& TemplateURL::keyword() const { | |
| 693 EnsureKeyword(); | |
| 694 return keyword_; | |
| 695 } | |
| 696 | |
| 697 void TemplateURL::EnsureKeyword() const { | |
| 698 if (autogenerate_keyword_ && !keyword_generated_) { | |
| 699 // Generate a keyword and cache it. | |
| 700 keyword_ = TemplateURLService::GenerateKeyword( | |
| 701 TemplateURLService::GenerateSearchURL(this).GetWithEmptyPath(), true); | |
| 702 keyword_generated_ = true; | |
| 703 } | |
| 704 } | |
| 705 | |
| 706 bool TemplateURL::ShowInDefaultList() const { | |
| 707 return show_in_default_list() && url_ref_.SupportsReplacement(); | |
| 708 } | |
| 709 | |
| 710 void TemplateURL::CopyURLRefs(const TemplateURL& other) { | |
| 711 url_ref_.InvalidateCachedValues(); | |
| 712 suggestions_url_ref_.InvalidateCachedValues(); | |
| 713 instant_url_ref_.InvalidateCachedValues(); | |
| 714 SetPrepopulateId(other.prepopulate_id_); | |
| 715 } | |
| 716 | |
| 717 void TemplateURL::SetPrepopulateId(int id) { | 706 void TemplateURL::SetPrepopulateId(int id) { |
| 718 prepopulate_id_ = id; | 707 data_.prepopulate_id = id; |
| 719 const bool prepopulated = id > 0; | 708 const bool prepopulated = id > 0; |
| 720 suggestions_url_ref_.prepopulated_ = prepopulated; | 709 suggestions_url_ref_.prepopulated_ = prepopulated; |
| 721 url_ref_.prepopulated_ = prepopulated; | 710 url_ref_.prepopulated_ = prepopulated; |
| 722 instant_url_ref_.prepopulated_ = prepopulated; | 711 instant_url_ref_.prepopulated_ = prepopulated; |
| 723 } | 712 } |
| 724 | 713 |
| 725 void TemplateURL::InvalidateCachedValues() const { | 714 void TemplateURL::InvalidateCachedValues() const { |
| 726 url_ref_.InvalidateCachedValues(); | 715 url_ref_.InvalidateCachedValues(); |
| 727 suggestions_url_ref_.InvalidateCachedValues(); | 716 suggestions_url_ref_.InvalidateCachedValues(); |
| 728 instant_url_ref_.InvalidateCachedValues(); | 717 instant_url_ref_.InvalidateCachedValues(); |
| 729 if (autogenerate_keyword_) { | 718 data_.SetAutogenerateKeyword(data_.autogenerate_keyword()); |
| 730 keyword_.clear(); | |
| 731 keyword_generated_ = false; | |
| 732 } | |
| 733 } | 719 } |
| 734 | |
| 735 bool TemplateURL::SupportsReplacement() const { | |
| 736 UIThreadSearchTermsData search_terms_data; | |
| 737 return SupportsReplacementUsingTermsData(search_terms_data); | |
| 738 } | |
| 739 | |
| 740 bool TemplateURL::SupportsReplacementUsingTermsData( | |
| 741 const SearchTermsData& search_terms_data) const { | |
| 742 return url_ref_.SupportsReplacementUsingTermsData(search_terms_data); | |
| 743 } | |
| 744 | |
| 745 std::string TemplateURL::GetExtensionId() const { | |
| 746 DCHECK(IsExtensionKeyword()); | |
| 747 return GURL(url_).host(); | |
| 748 } | |
| 749 | |
| 750 bool TemplateURL::IsExtensionKeyword() const { | |
| 751 return GURL(url_).SchemeIs(chrome::kExtensionScheme); | |
| 752 } | |
| OLD | NEW |