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 |