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/form_structure.h" | 5 #include "components/autofill/core/browser/form_structure.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
384 } // namespace | 384 } // namespace |
385 | 385 |
386 FormStructure::FormStructure(const FormData& form) | 386 FormStructure::FormStructure(const FormData& form) |
387 : form_name_(form.name), | 387 : form_name_(form.name), |
388 source_url_(form.origin), | 388 source_url_(form.origin), |
389 target_url_(form.action), | 389 target_url_(form.action), |
390 autofill_count_(0), | 390 autofill_count_(0), |
391 active_field_count_(0), | 391 active_field_count_(0), |
392 upload_required_(USE_UPLOAD_RATES), | 392 upload_required_(USE_UPLOAD_RATES), |
393 has_author_specified_types_(false), | 393 has_author_specified_types_(false), |
394 has_author_specified_sections_(false), | |
395 was_parsed_for_autocomplete_attributes_(false), | |
394 has_password_field_(false), | 396 has_password_field_(false), |
395 is_form_tag_(form.is_form_tag) { | 397 is_form_tag_(form.is_form_tag) { |
396 // Copy the form fields. | 398 // Copy the form fields. |
397 std::map<base::string16, size_t> unique_names; | 399 std::map<base::string16, size_t> unique_names; |
398 for (const FormFieldData& field : form.fields) { | 400 for (const FormFieldData& field : form.fields) { |
399 if (!ShouldSkipField(field)) { | 401 if (!ShouldSkipField(field)) { |
400 // Add all supported form fields (including with empty names) to the | 402 // Add all supported form fields (including with empty names) to the |
401 // signature. This is a requirement for Autofill servers. | 403 // signature. This is a requirement for Autofill servers. |
402 form_signature_field_names_.append("&"); | 404 form_signature_field_names_.append("&"); |
403 form_signature_field_names_.append(StripDigitsIfRequired(field.name)); | 405 form_signature_field_names_.append(StripDigitsIfRequired(field.name)); |
(...skipping 14 matching lines...) Expand all Loading... | |
418 } | 420 } |
419 } | 421 } |
420 | 422 |
421 FormStructure::~FormStructure() {} | 423 FormStructure::~FormStructure() {} |
422 | 424 |
423 void FormStructure::DetermineHeuristicTypes() { | 425 void FormStructure::DetermineHeuristicTypes() { |
424 // First, try to detect field types based on each field's |autocomplete| | 426 // First, try to detect field types based on each field's |autocomplete| |
425 // attribute value. If there is at least one form field that specifies an | 427 // attribute value. If there is at least one form field that specifies an |
426 // autocomplete type hint, don't try to apply other heuristics to match fields | 428 // autocomplete type hint, don't try to apply other heuristics to match fields |
427 // in this form. | 429 // in this form. |
428 bool has_author_specified_sections; | 430 if (!was_parsed_for_autocomplete_attributes_) |
429 ParseFieldTypesFromAutocompleteAttributes(&has_author_specified_types_, | 431 ParseFieldTypesFromAutocompleteAttributes(); |
430 &has_author_specified_sections); | |
431 | 432 |
432 if (!has_author_specified_types_) { | 433 if (!has_author_specified_types_) { |
433 ServerFieldTypeMap field_type_map; | 434 ServerFieldTypeMap field_type_map; |
434 FormField::ParseFormFields(fields_.get(), is_form_tag_, &field_type_map); | 435 FormField::ParseFormFields(fields_.get(), is_form_tag_, &field_type_map); |
435 for (size_t i = 0; i < field_count(); ++i) { | 436 for (size_t i = 0; i < field_count(); ++i) { |
436 AutofillField* field = fields_[i]; | 437 AutofillField* field = fields_[i]; |
437 ServerFieldTypeMap::iterator iter = | 438 ServerFieldTypeMap::iterator iter = |
438 field_type_map.find(field->unique_name()); | 439 field_type_map.find(field->unique_name()); |
439 if (iter != field_type_map.end()) | 440 if (iter != field_type_map.end()) |
440 field->set_heuristic_type(iter->second); | 441 field->set_heuristic_type(iter->second); |
441 } | 442 } |
442 } | 443 } |
443 | 444 |
444 UpdateAutofillCount(); | 445 UpdateAutofillCount(); |
445 IdentifySections(has_author_specified_sections); | 446 IdentifySections(has_author_specified_sections_); |
446 | 447 |
447 if (IsAutofillable()) { | 448 if (IsAutofillable()) { |
448 AutofillMetrics::LogDeveloperEngagementMetric( | 449 AutofillMetrics::LogDeveloperEngagementMetric( |
449 AutofillMetrics::FILLABLE_FORM_PARSED); | 450 AutofillMetrics::FILLABLE_FORM_PARSED); |
450 if (has_author_specified_types_) { | 451 if (has_author_specified_types_) { |
451 AutofillMetrics::LogDeveloperEngagementMetric( | 452 AutofillMetrics::LogDeveloperEngagementMetric( |
452 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS); | 453 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS); |
453 } | 454 } |
454 } | 455 } |
455 } | 456 } |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
735 | 736 |
736 void FormStructure::UpdateAutofillCount() { | 737 void FormStructure::UpdateAutofillCount() { |
737 autofill_count_ = 0; | 738 autofill_count_ = 0; |
738 for (const AutofillField* field : *this) { | 739 for (const AutofillField* field : *this) { |
739 if (field && field->IsFieldFillable()) | 740 if (field && field->IsFieldFillable()) |
740 ++autofill_count_; | 741 ++autofill_count_; |
741 } | 742 } |
742 } | 743 } |
743 | 744 |
744 bool FormStructure::ShouldBeParsed() const { | 745 bool FormStructure::ShouldBeParsed() const { |
745 if (active_field_count() < kRequiredAutofillFields) | 746 if (active_field_count() < kRequiredAutofillFields && |
747 !has_author_specified_types_) | |
Evan Stade
2015/11/04 17:15:19
curlies
sebsg
2015/11/10 19:04:51
Done.
| |
746 return false; | 748 return false; |
747 | 749 |
748 // Rule out http(s)://*/search?... | 750 // Rule out http(s)://*/search?... |
749 // e.g. http://www.google.com/search?q=... | 751 // e.g. http://www.google.com/search?q=... |
750 // http://search.yahoo.com/search?p=... | 752 // http://search.yahoo.com/search?p=... |
751 if (target_url_.path() == "/search") | 753 if (target_url_.path() == "/search") |
752 return false; | 754 return false; |
753 | 755 |
754 bool has_text_field = false; | 756 bool has_text_field = false; |
755 for (const AutofillField* it : *this) { | 757 for (const AutofillField* it : *this) { |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1065 EncodeFieldForQuery(*field, encompassing_xml_element); | 1067 EncodeFieldForQuery(*field, encompassing_xml_element); |
1066 break; | 1068 break; |
1067 case FormStructure::FIELD_ASSIGNMENTS: | 1069 case FormStructure::FIELD_ASSIGNMENTS: |
1068 EncodeFieldForFieldAssignments(*field, encompassing_xml_element); | 1070 EncodeFieldForFieldAssignments(*field, encompassing_xml_element); |
1069 break; | 1071 break; |
1070 } | 1072 } |
1071 } | 1073 } |
1072 return true; | 1074 return true; |
1073 } | 1075 } |
1074 | 1076 |
1075 void FormStructure::ParseFieldTypesFromAutocompleteAttributes( | 1077 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() { |
1076 bool* found_types, | |
1077 bool* found_sections) { | |
1078 const std::string kDefaultSection = "-default"; | 1078 const std::string kDefaultSection = "-default"; |
1079 | 1079 |
1080 *found_types = false; | 1080 has_author_specified_types_ = false; |
1081 *found_sections = false; | 1081 has_author_specified_sections_ = false; |
1082 for (AutofillField* field : fields_) { | 1082 for (std::vector<AutofillField*>::iterator it = fields_.begin(); |
1083 it != fields_.end(); ++it) { | |
Evan Stade
2015/11/04 17:15:19
why did you change teh format of this loop
sebsg
2015/11/10 19:04:51
Bad merge on PS#4, good catch!
| |
1084 AutofillField* field = *it; | |
1085 | |
1083 // To prevent potential section name collisions, add a default suffix for | 1086 // To prevent potential section name collisions, add a default suffix for |
1084 // other fields. Without this, 'autocomplete' attribute values | 1087 // other fields. Without this, 'autocomplete' attribute values |
1085 // "section--shipping street-address" and "shipping street-address" would be | 1088 // "section--shipping street-address" and "shipping street-address" would be |
1086 // parsed identically, given the section handling code below. We do this | 1089 // parsed identically, given the section handling code below. We do this |
1087 // before any validation so that fields with invalid attributes still end up | 1090 // before any validation so that fields with invalid attributes still end up |
1088 // in the default section. These default section names will be overridden | 1091 // in the default section. These default section names will be overridden |
1089 // by subsequent heuristic parsing steps if there are no author-specified | 1092 // by subsequent heuristic parsing steps if there are no author-specified |
1090 // section names. | 1093 // section names. |
1091 field->set_section(kDefaultSection); | 1094 field->set_section(kDefaultSection); |
1092 | 1095 |
1093 // Canonicalize the attribute value by trimming whitespace, collapsing | 1096 // Canonicalize the attribute value by trimming whitespace, collapsing |
1094 // non-space characters (e.g. tab) to spaces, and converting to lowercase. | 1097 // non-space characters (e.g. tab) to spaces, and converting to lowercase. |
1095 std::string autocomplete_attribute = | 1098 std::string autocomplete_attribute = |
1096 base::CollapseWhitespaceASCII(field->autocomplete_attribute, false); | 1099 base::CollapseWhitespaceASCII(field->autocomplete_attribute, false); |
1097 autocomplete_attribute = base::ToLowerASCII(autocomplete_attribute); | 1100 autocomplete_attribute = base::ToLowerASCII(autocomplete_attribute); |
1098 | 1101 |
1099 // The autocomplete attribute is overloaded: it can specify either a field | 1102 // The autocomplete attribute is overloaded: it can specify either a field |
1100 // type hint or whether autocomplete should be enabled at all. Ignore the | 1103 // type hint or whether autocomplete should be enabled at all. Ignore the |
1101 // latter type of attribute value. | 1104 // latter type of attribute value. |
1102 if (autocomplete_attribute.empty() || | 1105 if (autocomplete_attribute.empty() || |
1103 autocomplete_attribute == "on" || | 1106 autocomplete_attribute == "on" || |
1104 autocomplete_attribute == "off") { | 1107 autocomplete_attribute == "off") { |
1105 continue; | 1108 continue; |
1106 } | 1109 } |
1107 | 1110 |
1108 // Any other value, even it is invalid, is considered to be a type hint. | 1111 // Any other value, even it is invalid, is considered to be a type hint. |
1109 // This allows a website's author to specify an attribute like | 1112 // This allows a website's author to specify an attribute like |
1110 // autocomplete="other" on a field to disable all Autofill heuristics for | 1113 // autocomplete="other" on a field to disable all Autofill heuristics for |
1111 // the form. | 1114 // the form. |
1112 *found_types = true; | 1115 has_author_specified_types_ = true; |
1113 | 1116 |
1114 // Tokenize the attribute value. Per the spec, the tokens are parsed in | 1117 // Tokenize the attribute value. Per the spec, the tokens are parsed in |
1115 // reverse order. | 1118 // reverse order. |
1116 std::vector<std::string> tokens = base::SplitString( | 1119 std::vector<std::string> tokens = base::SplitString( |
1117 autocomplete_attribute, " ", base::KEEP_WHITESPACE, | 1120 autocomplete_attribute, " ", base::KEEP_WHITESPACE, |
1118 base::SPLIT_WANT_NONEMPTY); | 1121 base::SPLIT_WANT_NONEMPTY); |
1119 | 1122 |
1120 // The final token must be the field type. | 1123 // The final token must be the field type. |
1121 // If it is not one of the known types, abort. | 1124 // If it is not one of the known types, abort. |
1122 DCHECK(!tokens.empty()); | 1125 DCHECK(!tokens.empty()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1165 // Prepend this section name to the suffix set in the preceding block. | 1168 // Prepend this section name to the suffix set in the preceding block. |
1166 section = tokens.back().substr(kSectionPrefix.size()) + section; | 1169 section = tokens.back().substr(kSectionPrefix.size()) + section; |
1167 tokens.pop_back(); | 1170 tokens.pop_back(); |
1168 } | 1171 } |
1169 | 1172 |
1170 // No other tokens are allowed. If there are any remaining, abort. | 1173 // No other tokens are allowed. If there are any remaining, abort. |
1171 if (!tokens.empty()) | 1174 if (!tokens.empty()) |
1172 continue; | 1175 continue; |
1173 | 1176 |
1174 if (section != kDefaultSection) { | 1177 if (section != kDefaultSection) { |
1175 *found_sections = true; | 1178 has_author_specified_sections_ = true; |
1176 field->set_section(section); | 1179 field->set_section(section); |
1177 } | 1180 } |
1178 | 1181 |
1179 // No errors encountered while parsing! | 1182 // No errors encountered while parsing! |
1180 // Update the |field|'s type based on what was parsed from the attribute. | 1183 // Update the |field|'s type based on what was parsed from the attribute. |
1181 field->SetHtmlType(field_type, mode); | 1184 field->SetHtmlType(field_type, mode); |
1182 } | 1185 } |
1186 | |
1187 was_parsed_for_autocomplete_attributes_ = true; | |
1183 } | 1188 } |
1184 | 1189 |
1185 bool FormStructure::FillFields( | 1190 bool FormStructure::FillFields( |
1186 const std::vector<ServerFieldType>& types, | 1191 const std::vector<ServerFieldType>& types, |
1187 const InputFieldComparator& matches, | 1192 const InputFieldComparator& matches, |
1188 const base::Callback<base::string16(const AutofillType&)>& get_info, | 1193 const base::Callback<base::string16(const AutofillType&)>& get_info, |
1189 const std::string& address_language_code, | 1194 const std::string& address_language_code, |
1190 const std::string& app_locale) { | 1195 const std::string& app_locale) { |
1191 bool filled_something = false; | 1196 bool filled_something = false; |
1192 for (size_t i = 0; i < field_count(); ++i) { | 1197 for (size_t i = 0; i < field_count(); ++i) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1321 for (AutofillField* field : fields_) { | 1326 for (AutofillField* field : fields_) { |
1322 FieldTypeGroup field_type_group = field->Type().group(); | 1327 FieldTypeGroup field_type_group = field->Type().group(); |
1323 if (field_type_group == CREDIT_CARD) | 1328 if (field_type_group == CREDIT_CARD) |
1324 field->set_section(field->section() + "-cc"); | 1329 field->set_section(field->section() + "-cc"); |
1325 else | 1330 else |
1326 field->set_section(field->section() + "-default"); | 1331 field->set_section(field->section() + "-default"); |
1327 } | 1332 } |
1328 } | 1333 } |
1329 | 1334 |
1330 } // namespace autofill | 1335 } // namespace autofill |
OLD | NEW |