Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "components/autofill/core/browser/autofill_profile.h" | 5 #include "components/autofill/core/browser/autofill_profile.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <functional> | 8 #include <functional> |
| 9 #include <map> | 9 #include <map> |
| 10 #include <ostream> | 10 #include <ostream> |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 152 const std::vector<T>& form_group_items, | 152 const std::vector<T>& form_group_items, |
| 153 const std::string& app_locale, | 153 const std::string& app_locale, |
| 154 std::vector<base::string16>* values) { | 154 std::vector<base::string16>* values) { |
| 155 values->resize(form_group_items.size()); | 155 values->resize(form_group_items.size()); |
| 156 for (size_t i = 0; i < values->size(); ++i) { | 156 for (size_t i = 0; i < values->size(); ++i) { |
| 157 (*values)[i] = GetFormGroupInfo(form_group_items[i], type, app_locale); | 157 (*values)[i] = GetFormGroupInfo(form_group_items[i], type, app_locale); |
| 158 } | 158 } |
| 159 } | 159 } |
| 160 | 160 |
| 161 // Collapse compound field types to their "full" type. I.e. First name | 161 // Collapse compound field types to their "full" type. I.e. First name |
| 162 // collapses to full name, area code collapses to full phone, etc. | 162 // collapses to full name, area code collapses to full phone, etc. |
|
Ilya Sherman
2014/06/24 07:21:37
Please update this comment.
Evan Stade
2014/06/27 00:06:19
reverted the change
| |
| 163 void CollapseCompoundFieldTypes(ServerFieldTypeSet* type_set) { | 163 void CollapseCompoundFieldTypes(ServerFieldTypeSet* type_set) { |
| 164 ServerFieldTypeSet collapsed_set; | 164 ServerFieldTypeSet collapsed_set; |
| 165 for (ServerFieldTypeSet::iterator it = type_set->begin(); | 165 for (ServerFieldTypeSet::iterator it = type_set->begin(); |
| 166 it != type_set->end(); ++it) { | 166 it != type_set->end(); ++it) { |
| 167 switch (*it) { | 167 switch (*it) { |
| 168 case NAME_FIRST: | |
| 169 case NAME_MIDDLE: | 168 case NAME_MIDDLE: |
| 170 case NAME_LAST: | |
| 171 case NAME_MIDDLE_INITIAL: | 169 case NAME_MIDDLE_INITIAL: |
| 170 collapsed_set.insert(NAME_MIDDLE); | |
| 171 break; | |
| 172 | |
| 172 case NAME_FULL: | 173 case NAME_FULL: |
| 173 case NAME_SUFFIX: | 174 case NAME_SUFFIX: |
| 174 collapsed_set.insert(NAME_FULL); | 175 collapsed_set.insert(NAME_FULL); |
| 175 break; | 176 break; |
| 176 | 177 |
| 177 case PHONE_HOME_NUMBER: | 178 case PHONE_HOME_NUMBER: |
| 178 case PHONE_HOME_CITY_CODE: | 179 case PHONE_HOME_CITY_CODE: |
| 179 case PHONE_HOME_COUNTRY_CODE: | 180 case PHONE_HOME_COUNTRY_CODE: |
| 180 case PHONE_HOME_CITY_AND_NUMBER: | 181 case PHONE_HOME_CITY_AND_NUMBER: |
| 181 case PHONE_HOME_WHOLE_NUMBER: | 182 case PHONE_HOME_WHOLE_NUMBER: |
| (...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 570 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile, | 571 void AutofillProfile::OverwriteWithOrAddTo(const AutofillProfile& profile, |
| 571 const std::string& app_locale) { | 572 const std::string& app_locale) { |
| 572 // Verified profiles should never be overwritten with unverified data. | 573 // Verified profiles should never be overwritten with unverified data. |
| 573 DCHECK(!IsVerified() || profile.IsVerified()); | 574 DCHECK(!IsVerified() || profile.IsVerified()); |
| 574 set_origin(profile.origin()); | 575 set_origin(profile.origin()); |
| 575 set_language_code(profile.language_code()); | 576 set_language_code(profile.language_code()); |
| 576 | 577 |
| 577 ServerFieldTypeSet field_types; | 578 ServerFieldTypeSet field_types; |
| 578 profile.GetNonEmptyTypes(app_locale, &field_types); | 579 profile.GetNonEmptyTypes(app_locale, &field_types); |
| 579 | 580 |
| 580 // Only transfer "full" types (e.g. full name) and not fragments (e.g. | 581 // Only transfer "full" types (e.g. full phone number) and not fragments (e.g. |
| 581 // first name, last name). | 582 // first name, last name). |
|
Ilya Sherman
2014/06/24 07:21:37
This comment needs more updating.
Evan Stade
2014/06/27 00:06:18
reverted
| |
| 582 CollapseCompoundFieldTypes(&field_types); | 583 CollapseCompoundFieldTypes(&field_types); |
|
Ilya Sherman
2014/06/24 07:21:37
I'm concerned that treating first, middle, last, a
Evan Stade
2014/06/27 00:06:19
Quite right, I didn't look at this closely enough
| |
| 583 | 584 |
| 584 // TODO(isherman): Revisit this decision in the context of i18n and storing | 585 // TODO(isherman): Revisit this decision in the context of i18n and storing |
| 585 // full addresses rather than storing 1-to-2 lines of an address. | 586 // full addresses rather than storing 1-to-2 lines of an address. |
| 586 // For addresses, do the opposite: transfer individual address lines, rather | 587 // For addresses, do the opposite: transfer individual address lines, rather |
| 587 // than full addresses. | 588 // than full addresses. |
| 588 field_types.erase(ADDRESS_HOME_STREET_ADDRESS); | 589 field_types.erase(ADDRESS_HOME_STREET_ADDRESS); |
| 589 | 590 |
| 590 for (ServerFieldTypeSet::const_iterator iter = field_types.begin(); | 591 for (ServerFieldTypeSet::const_iterator iter = field_types.begin(); |
| 591 iter != field_types.end(); ++iter) { | 592 iter != field_types.end(); ++iter) { |
| 592 if (AutofillProfile::SupportsMultiValue(*iter)) { | 593 if (AutofillProfile::SupportsMultiValue(*iter)) { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 636 return group == NAME || | 637 return group == NAME || |
| 637 group == NAME_BILLING || | 638 group == NAME_BILLING || |
| 638 group == EMAIL || | 639 group == EMAIL || |
| 639 group == PHONE_HOME || | 640 group == PHONE_HOME || |
| 640 group == PHONE_BILLING; | 641 group == PHONE_BILLING; |
| 641 } | 642 } |
| 642 | 643 |
| 643 // static | 644 // static |
| 644 void AutofillProfile::CreateDifferentiatingLabels( | 645 void AutofillProfile::CreateDifferentiatingLabels( |
| 645 const std::vector<AutofillProfile*>& profiles, | 646 const std::vector<AutofillProfile*>& profiles, |
| 647 const std::string& app_locale, | |
| 646 std::vector<base::string16>* labels) { | 648 std::vector<base::string16>* labels) { |
| 647 const size_t kMinimalFieldsShown = 2; | 649 const size_t kMinimalFieldsShown = 2; |
| 648 CreateInferredLabels(profiles, NULL, UNKNOWN_TYPE, kMinimalFieldsShown, | 650 CreateInferredLabels(profiles, NULL, UNKNOWN_TYPE, kMinimalFieldsShown, |
| 649 labels); | 651 app_locale, labels); |
| 650 DCHECK_EQ(profiles.size(), labels->size()); | 652 DCHECK_EQ(profiles.size(), labels->size()); |
| 651 } | 653 } |
| 652 | 654 |
| 653 // static | 655 // static |
| 654 void AutofillProfile::CreateInferredLabels( | 656 void AutofillProfile::CreateInferredLabels( |
| 655 const std::vector<AutofillProfile*>& profiles, | 657 const std::vector<AutofillProfile*>& profiles, |
| 656 const std::vector<ServerFieldType>* suggested_fields, | 658 const std::vector<ServerFieldType>* suggested_fields, |
| 657 ServerFieldType excluded_field, | 659 ServerFieldType excluded_field, |
| 658 size_t minimal_fields_shown, | 660 size_t minimal_fields_shown, |
| 661 const std::string& app_locale, | |
| 659 std::vector<base::string16>* labels) { | 662 std::vector<base::string16>* labels) { |
| 660 std::vector<ServerFieldType> fields_to_use; | 663 std::vector<ServerFieldType> fields_to_use; |
| 661 GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field, | 664 GetFieldsForDistinguishingProfiles(suggested_fields, excluded_field, |
| 662 &fields_to_use); | 665 &fields_to_use); |
| 663 | 666 |
| 664 // Construct the default label for each profile. Also construct a map that | 667 // Construct the default label for each profile. Also construct a map that |
| 665 // associates each label with the profiles that have this label. This map is | 668 // associates each label with the profiles that have this label. This map is |
| 666 // then used to detect which labels need further differentiating fields. | 669 // then used to detect which labels need further differentiating fields. |
| 667 std::map<base::string16, std::list<size_t> > labels_to_profiles; | 670 std::map<base::string16, std::list<size_t> > labels_to_profiles; |
| 668 for (size_t i = 0; i < profiles.size(); ++i) { | 671 for (size_t i = 0; i < profiles.size(); ++i) { |
| 669 base::string16 label = | 672 base::string16 label = |
| 670 profiles[i]->ConstructInferredLabel(fields_to_use, | 673 profiles[i]->ConstructInferredLabel(fields_to_use, |
| 671 minimal_fields_shown); | 674 minimal_fields_shown, |
| 675 app_locale); | |
| 672 labels_to_profiles[label].push_back(i); | 676 labels_to_profiles[label].push_back(i); |
| 673 } | 677 } |
| 674 | 678 |
| 675 labels->resize(profiles.size()); | 679 labels->resize(profiles.size()); |
| 676 for (std::map<base::string16, std::list<size_t> >::const_iterator it = | 680 for (std::map<base::string16, std::list<size_t> >::const_iterator it = |
| 677 labels_to_profiles.begin(); | 681 labels_to_profiles.begin(); |
| 678 it != labels_to_profiles.end(); ++it) { | 682 it != labels_to_profiles.end(); ++it) { |
| 679 if (it->second.size() == 1) { | 683 if (it->second.size() == 1) { |
| 680 // This label is unique, so use it without any further ado. | 684 // This label is unique, so use it without any further ado. |
| 681 base::string16 label = it->first; | 685 base::string16 label = it->first; |
| 682 size_t profile_index = it->second.front(); | 686 size_t profile_index = it->second.front(); |
| 683 (*labels)[profile_index] = label; | 687 (*labels)[profile_index] = label; |
| 684 } else { | 688 } else { |
| 685 // We have more than one profile with the same label, so add | 689 // We have more than one profile with the same label, so add |
| 686 // differentiating fields. | 690 // differentiating fields. |
| 687 CreateInferredLabelsHelper(profiles, it->second, fields_to_use, | 691 CreateInferredLabelsHelper(profiles, it->second, fields_to_use, |
| 688 minimal_fields_shown, labels); | 692 minimal_fields_shown, app_locale, labels); |
| 689 } | 693 } |
| 690 } | 694 } |
| 691 } | 695 } |
| 692 | 696 |
| 693 void AutofillProfile::GetSupportedTypes( | 697 void AutofillProfile::GetSupportedTypes( |
| 694 ServerFieldTypeSet* supported_types) const { | 698 ServerFieldTypeSet* supported_types) const { |
| 695 FormGroupList info = FormGroups(); | 699 FormGroupList info = FormGroups(); |
| 696 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) | 700 for (FormGroupList::const_iterator it = info.begin(); it != info.end(); ++it) |
| 697 (*it)->GetSupportedTypes(supported_types); | 701 (*it)->GetSupportedTypes(supported_types); |
| 698 } | 702 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 730 base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); | 734 base::UTF16ToASCII(GetRawInfo(ADDRESS_HOME_COUNTRY)); |
| 731 if (std::find_if(existing_phones->begin(), existing_phones->end(), | 735 if (std::find_if(existing_phones->begin(), existing_phones->end(), |
| 732 FindByPhone(phone, country_code, app_locale)) == | 736 FindByPhone(phone, country_code, app_locale)) == |
| 733 existing_phones->end()) { | 737 existing_phones->end()) { |
| 734 existing_phones->push_back(phone); | 738 existing_phones->push_back(phone); |
| 735 } | 739 } |
| 736 } | 740 } |
| 737 | 741 |
| 738 base::string16 AutofillProfile::ConstructInferredLabel( | 742 base::string16 AutofillProfile::ConstructInferredLabel( |
| 739 const std::vector<ServerFieldType>& included_fields, | 743 const std::vector<ServerFieldType>& included_fields, |
| 740 size_t num_fields_to_use) const { | 744 size_t num_fields_to_use, |
| 745 const std::string& app_locale) const { | |
| 741 const base::string16 separator = | 746 const base::string16 separator = |
| 742 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); | 747 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR); |
| 743 | 748 |
| 744 base::string16 label; | 749 base::string16 label; |
| 745 size_t num_fields_used = 0; | 750 size_t num_fields_used = 0; |
| 746 for (std::vector<ServerFieldType>::const_iterator it = | 751 for (std::vector<ServerFieldType>::const_iterator it = |
| 747 included_fields.begin(); | 752 included_fields.begin(); |
| 748 it != included_fields.end() && num_fields_used < num_fields_to_use; | 753 it != included_fields.end() && num_fields_used < num_fields_to_use; |
| 749 ++it) { | 754 ++it) { |
| 750 base::string16 field = GetRawInfo(*it); | 755 base::string16 field = GetInfo(AutofillType(*it), app_locale); |
| 751 if (field.empty()) | 756 if (field.empty()) |
| 752 continue; | 757 continue; |
| 753 | 758 |
| 754 if (!label.empty()) | 759 if (!label.empty()) |
| 755 label.append(separator); | 760 label.append(separator); |
| 756 | 761 |
| 757 label.append(field); | 762 label.append(field); |
| 758 ++num_fields_used; | 763 ++num_fields_used; |
| 759 } | 764 } |
| 760 | 765 |
| 761 // Flatten the label if need be. | 766 // Flatten the label if need be. |
| 762 const base::string16& line_separator = | 767 const base::string16& line_separator = |
| 763 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR); | 768 l10n_util::GetStringUTF16(IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR); |
| 764 base::ReplaceChars(label, base::ASCIIToUTF16("\n"), line_separator, &label); | 769 base::ReplaceChars(label, base::ASCIIToUTF16("\n"), line_separator, &label); |
| 765 | 770 |
| 766 return label; | 771 return label; |
| 767 } | 772 } |
| 768 | 773 |
| 769 // static | 774 // static |
| 770 void AutofillProfile::CreateInferredLabelsHelper( | 775 void AutofillProfile::CreateInferredLabelsHelper( |
| 771 const std::vector<AutofillProfile*>& profiles, | 776 const std::vector<AutofillProfile*>& profiles, |
| 772 const std::list<size_t>& indices, | 777 const std::list<size_t>& indices, |
| 773 const std::vector<ServerFieldType>& fields, | 778 const std::vector<ServerFieldType>& fields, |
| 774 size_t num_fields_to_include, | 779 size_t num_fields_to_include, |
| 780 const std::string& app_locale, | |
| 775 std::vector<base::string16>* labels) { | 781 std::vector<base::string16>* labels) { |
| 776 // For efficiency, we first construct a map of fields to their text values and | 782 // For efficiency, we first construct a map of fields to their text values and |
| 777 // each value's frequency. | 783 // each value's frequency. |
| 778 std::map<ServerFieldType, | 784 std::map<ServerFieldType, |
| 779 std::map<base::string16, size_t> > field_text_frequencies_by_field; | 785 std::map<base::string16, size_t> > field_text_frequencies_by_field; |
| 780 for (std::vector<ServerFieldType>::const_iterator field = fields.begin(); | 786 for (std::vector<ServerFieldType>::const_iterator field = fields.begin(); |
| 781 field != fields.end(); ++field) { | 787 field != fields.end(); ++field) { |
| 782 std::map<base::string16, size_t>& field_text_frequencies = | 788 std::map<base::string16, size_t>& field_text_frequencies = |
| 783 field_text_frequencies_by_field[*field]; | 789 field_text_frequencies_by_field[*field]; |
| 784 | 790 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 | 836 |
| 831 label_fields.push_back(*field); | 837 label_fields.push_back(*field); |
| 832 | 838 |
| 833 // If we've (1) found a differentiating field and (2) found at least | 839 // If we've (1) found a differentiating field and (2) found at least |
| 834 // |num_fields_to_include| non-empty fields, we're done! | 840 // |num_fields_to_include| non-empty fields, we're done! |
| 835 if (found_differentiating_field && | 841 if (found_differentiating_field && |
| 836 label_fields.size() >= num_fields_to_include) | 842 label_fields.size() >= num_fields_to_include) |
| 837 break; | 843 break; |
| 838 } | 844 } |
| 839 | 845 |
| 840 (*labels)[*it] = | 846 (*labels)[*it] = profile->ConstructInferredLabel( |
| 841 profile->ConstructInferredLabel(label_fields, label_fields.size()); | 847 label_fields, label_fields.size(), app_locale); |
| 842 } | 848 } |
| 843 } | 849 } |
| 844 | 850 |
| 845 AutofillProfile::FormGroupList AutofillProfile::FormGroups() const { | 851 AutofillProfile::FormGroupList AutofillProfile::FormGroups() const { |
| 846 FormGroupList v(5); | 852 FormGroupList v(5); |
| 847 v[0] = &name_[0]; | 853 v[0] = &name_[0]; |
| 848 v[1] = &email_[0]; | 854 v[1] = &email_[0]; |
| 849 v[2] = &company_; | 855 v[2] = &company_; |
| 850 v[3] = &phone_number_[0]; | 856 v[3] = &phone_number_[0]; |
| 851 v[4] = &address_; | 857 v[4] = &address_; |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 919 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) | 925 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE)) |
| 920 << " " | 926 << " " |
| 921 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) | 927 << UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY)) |
| 922 << " " | 928 << " " |
| 923 << profile.language_code() | 929 << profile.language_code() |
| 924 << " " | 930 << " " |
| 925 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)); | 931 << UTF16ToUTF8(MultiString(profile, PHONE_HOME_WHOLE_NUMBER)); |
| 926 } | 932 } |
| 927 | 933 |
| 928 } // namespace autofill | 934 } // namespace autofill |
| OLD | NEW |