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 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 } // namespace | 382 } // namespace |
383 | 383 |
384 FormStructure::FormStructure(const FormData& form) | 384 FormStructure::FormStructure(const FormData& form) |
385 : form_name_(form.name), | 385 : form_name_(form.name), |
386 source_url_(form.origin), | 386 source_url_(form.origin), |
387 target_url_(form.action), | 387 target_url_(form.action), |
388 autofill_count_(0), | 388 autofill_count_(0), |
389 active_field_count_(0), | 389 active_field_count_(0), |
390 upload_required_(USE_UPLOAD_RATES), | 390 upload_required_(USE_UPLOAD_RATES), |
391 has_author_specified_types_(false), | 391 has_author_specified_types_(false), |
| 392 has_author_specified_sections_(false), |
| 393 was_parsed_for_autocomplete_attributes_(false), |
392 has_password_field_(false), | 394 has_password_field_(false), |
393 is_form_tag_(form.is_form_tag) { | 395 is_form_tag_(form.is_form_tag) { |
394 // Copy the form fields. | 396 // Copy the form fields. |
395 std::map<base::string16, size_t> unique_names; | 397 std::map<base::string16, size_t> unique_names; |
396 for (const FormFieldData& field : form.fields) { | 398 for (const FormFieldData& field : form.fields) { |
397 if (!ShouldSkipField(field)) { | 399 if (!ShouldSkipField(field)) { |
398 // Add all supported form fields (including with empty names) to the | 400 // Add all supported form fields (including with empty names) to the |
399 // signature. This is a requirement for Autofill servers. | 401 // signature. This is a requirement for Autofill servers. |
400 form_signature_field_names_.append("&"); | 402 form_signature_field_names_.append("&"); |
401 form_signature_field_names_.append(StripDigitsIfRequired(field.name)); | 403 form_signature_field_names_.append(StripDigitsIfRequired(field.name)); |
(...skipping 14 matching lines...) Expand all Loading... |
416 } | 418 } |
417 } | 419 } |
418 | 420 |
419 FormStructure::~FormStructure() {} | 421 FormStructure::~FormStructure() {} |
420 | 422 |
421 void FormStructure::DetermineHeuristicTypes() { | 423 void FormStructure::DetermineHeuristicTypes() { |
422 // First, try to detect field types based on each field's |autocomplete| | 424 // First, try to detect field types based on each field's |autocomplete| |
423 // attribute value. If there is at least one form field that specifies an | 425 // attribute value. If there is at least one form field that specifies an |
424 // autocomplete type hint, don't try to apply other heuristics to match fields | 426 // autocomplete type hint, don't try to apply other heuristics to match fields |
425 // in this form. | 427 // in this form. |
426 bool has_author_specified_sections; | 428 if (!was_parsed_for_autocomplete_attributes_) |
427 ParseFieldTypesFromAutocompleteAttributes(&has_author_specified_types_, | 429 ParseFieldTypesFromAutocompleteAttributes(); |
428 &has_author_specified_sections); | |
429 | 430 |
430 if (!has_author_specified_types_) { | 431 if (!has_author_specified_types_) { |
431 ServerFieldTypeMap field_type_map; | 432 ServerFieldTypeMap field_type_map; |
432 FormField::ParseFormFields(fields_.get(), is_form_tag_, &field_type_map); | 433 FormField::ParseFormFields(fields_.get(), is_form_tag_, &field_type_map); |
433 for (size_t i = 0; i < field_count(); ++i) { | 434 for (size_t i = 0; i < field_count(); ++i) { |
434 AutofillField* field = fields_[i]; | 435 AutofillField* field = fields_[i]; |
435 ServerFieldTypeMap::iterator iter = | 436 ServerFieldTypeMap::iterator iter = |
436 field_type_map.find(field->unique_name()); | 437 field_type_map.find(field->unique_name()); |
437 if (iter != field_type_map.end()) | 438 if (iter != field_type_map.end()) |
438 field->set_heuristic_type(iter->second); | 439 field->set_heuristic_type(iter->second); |
439 } | 440 } |
440 } | 441 } |
441 | 442 |
442 UpdateAutofillCount(); | 443 UpdateAutofillCount(); |
443 IdentifySections(has_author_specified_sections); | 444 IdentifySections(has_author_specified_sections_); |
444 | 445 |
445 if (IsAutofillable()) { | 446 if (IsAutofillable()) { |
446 AutofillMetrics::LogDeveloperEngagementMetric( | 447 AutofillMetrics::LogDeveloperEngagementMetric( |
447 AutofillMetrics::FILLABLE_FORM_PARSED); | 448 AutofillMetrics::FILLABLE_FORM_PARSED); |
448 if (has_author_specified_types_) { | 449 if (has_author_specified_types_) { |
449 AutofillMetrics::LogDeveloperEngagementMetric( | 450 AutofillMetrics::LogDeveloperEngagementMetric( |
450 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS); | 451 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS); |
451 } | 452 } |
452 } | 453 } |
453 } | 454 } |
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
739 autofill_count_ = 0; | 740 autofill_count_ = 0; |
740 for (std::vector<AutofillField*>::const_iterator iter = begin(); | 741 for (std::vector<AutofillField*>::const_iterator iter = begin(); |
741 iter != end(); ++iter) { | 742 iter != end(); ++iter) { |
742 AutofillField* field = *iter; | 743 AutofillField* field = *iter; |
743 if (field && field->IsFieldFillable()) | 744 if (field && field->IsFieldFillable()) |
744 ++autofill_count_; | 745 ++autofill_count_; |
745 } | 746 } |
746 } | 747 } |
747 | 748 |
748 bool FormStructure::ShouldBeParsed() const { | 749 bool FormStructure::ShouldBeParsed() const { |
749 if (active_field_count() < kRequiredAutofillFields) | 750 if (active_field_count() < kRequiredAutofillFields && |
| 751 !has_author_specified_types_) |
750 return false; | 752 return false; |
751 | 753 |
752 // Rule out http(s)://*/search?... | 754 // Rule out http(s)://*/search?... |
753 // e.g. http://www.google.com/search?q=... | 755 // e.g. http://www.google.com/search?q=... |
754 // http://search.yahoo.com/search?p=... | 756 // http://search.yahoo.com/search?p=... |
755 if (target_url_.path() == "/search") | 757 if (target_url_.path() == "/search") |
756 return false; | 758 return false; |
757 | 759 |
758 bool has_text_field = false; | 760 bool has_text_field = false; |
759 for (std::vector<AutofillField*>::const_iterator it = begin(); | 761 for (std::vector<AutofillField*>::const_iterator it = begin(); |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1075 EncodeFieldForQuery(*field, encompassing_xml_element); | 1077 EncodeFieldForQuery(*field, encompassing_xml_element); |
1076 break; | 1078 break; |
1077 case FormStructure::FIELD_ASSIGNMENTS: | 1079 case FormStructure::FIELD_ASSIGNMENTS: |
1078 EncodeFieldForFieldAssignments(*field, encompassing_xml_element); | 1080 EncodeFieldForFieldAssignments(*field, encompassing_xml_element); |
1079 break; | 1081 break; |
1080 } | 1082 } |
1081 } | 1083 } |
1082 return true; | 1084 return true; |
1083 } | 1085 } |
1084 | 1086 |
1085 void FormStructure::ParseFieldTypesFromAutocompleteAttributes( | 1087 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() { |
1086 bool* found_types, | |
1087 bool* found_sections) { | |
1088 const std::string kDefaultSection = "-default"; | 1088 const std::string kDefaultSection = "-default"; |
1089 | 1089 |
1090 *found_types = false; | 1090 has_author_specified_types_ = false; |
1091 *found_sections = false; | 1091 has_author_specified_sections_ = false; |
1092 for (std::vector<AutofillField*>::iterator it = fields_.begin(); | 1092 for (std::vector<AutofillField*>::iterator it = fields_.begin(); |
1093 it != fields_.end(); ++it) { | 1093 it != fields_.end(); ++it) { |
1094 AutofillField* field = *it; | 1094 AutofillField* field = *it; |
1095 | 1095 |
1096 // To prevent potential section name collisions, add a default suffix for | 1096 // To prevent potential section name collisions, add a default suffix for |
1097 // other fields. Without this, 'autocomplete' attribute values | 1097 // other fields. Without this, 'autocomplete' attribute values |
1098 // "section--shipping street-address" and "shipping street-address" would be | 1098 // "section--shipping street-address" and "shipping street-address" would be |
1099 // parsed identically, given the section handling code below. We do this | 1099 // parsed identically, given the section handling code below. We do this |
1100 // before any validation so that fields with invalid attributes still end up | 1100 // before any validation so that fields with invalid attributes still end up |
1101 // in the default section. These default section names will be overridden | 1101 // in the default section. These default section names will be overridden |
(...skipping 13 matching lines...) Expand all Loading... |
1115 if (autocomplete_attribute.empty() || | 1115 if (autocomplete_attribute.empty() || |
1116 autocomplete_attribute == "on" || | 1116 autocomplete_attribute == "on" || |
1117 autocomplete_attribute == "off") { | 1117 autocomplete_attribute == "off") { |
1118 continue; | 1118 continue; |
1119 } | 1119 } |
1120 | 1120 |
1121 // Any other value, even it is invalid, is considered to be a type hint. | 1121 // Any other value, even it is invalid, is considered to be a type hint. |
1122 // This allows a website's author to specify an attribute like | 1122 // This allows a website's author to specify an attribute like |
1123 // autocomplete="other" on a field to disable all Autofill heuristics for | 1123 // autocomplete="other" on a field to disable all Autofill heuristics for |
1124 // the form. | 1124 // the form. |
1125 *found_types = true; | 1125 has_author_specified_types_ = true; |
1126 | 1126 |
1127 // Tokenize the attribute value. Per the spec, the tokens are parsed in | 1127 // Tokenize the attribute value. Per the spec, the tokens are parsed in |
1128 // reverse order. | 1128 // reverse order. |
1129 std::vector<std::string> tokens = base::SplitString( | 1129 std::vector<std::string> tokens = base::SplitString( |
1130 autocomplete_attribute, " ", base::KEEP_WHITESPACE, | 1130 autocomplete_attribute, " ", base::KEEP_WHITESPACE, |
1131 base::SPLIT_WANT_NONEMPTY); | 1131 base::SPLIT_WANT_NONEMPTY); |
1132 | 1132 |
1133 // The final token must be the field type. | 1133 // The final token must be the field type. |
1134 // If it is not one of the known types, abort. | 1134 // If it is not one of the known types, abort. |
1135 DCHECK(!tokens.empty()); | 1135 DCHECK(!tokens.empty()); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1178 // Prepend this section name to the suffix set in the preceding block. | 1178 // Prepend this section name to the suffix set in the preceding block. |
1179 section = tokens.back().substr(kSectionPrefix.size()) + section; | 1179 section = tokens.back().substr(kSectionPrefix.size()) + section; |
1180 tokens.pop_back(); | 1180 tokens.pop_back(); |
1181 } | 1181 } |
1182 | 1182 |
1183 // No other tokens are allowed. If there are any remaining, abort. | 1183 // No other tokens are allowed. If there are any remaining, abort. |
1184 if (!tokens.empty()) | 1184 if (!tokens.empty()) |
1185 continue; | 1185 continue; |
1186 | 1186 |
1187 if (section != kDefaultSection) { | 1187 if (section != kDefaultSection) { |
1188 *found_sections = true; | 1188 has_author_specified_sections_ = true; |
1189 field->set_section(section); | 1189 field->set_section(section); |
1190 } | 1190 } |
1191 | 1191 |
1192 // No errors encountered while parsing! | 1192 // No errors encountered while parsing! |
1193 // Update the |field|'s type based on what was parsed from the attribute. | 1193 // Update the |field|'s type based on what was parsed from the attribute. |
1194 field->SetHtmlType(field_type, mode); | 1194 field->SetHtmlType(field_type, mode); |
1195 } | 1195 } |
| 1196 |
| 1197 was_parsed_for_autocomplete_attributes_ = true; |
1196 } | 1198 } |
1197 | 1199 |
1198 bool FormStructure::FillFields( | 1200 bool FormStructure::FillFields( |
1199 const std::vector<ServerFieldType>& types, | 1201 const std::vector<ServerFieldType>& types, |
1200 const InputFieldComparator& matches, | 1202 const InputFieldComparator& matches, |
1201 const base::Callback<base::string16(const AutofillType&)>& get_info, | 1203 const base::Callback<base::string16(const AutofillType&)>& get_info, |
1202 const std::string& address_language_code, | 1204 const std::string& address_language_code, |
1203 const std::string& app_locale) { | 1205 const std::string& app_locale) { |
1204 bool filled_something = false; | 1206 bool filled_something = false; |
1205 for (size_t i = 0; i < field_count(); ++i) { | 1207 for (size_t i = 0; i < field_count(); ++i) { |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1334 for (AutofillField* field : fields_) { | 1336 for (AutofillField* field : fields_) { |
1335 FieldTypeGroup field_type_group = field->Type().group(); | 1337 FieldTypeGroup field_type_group = field->Type().group(); |
1336 if (field_type_group == CREDIT_CARD) | 1338 if (field_type_group == CREDIT_CARD) |
1337 field->set_section(field->section() + "-cc"); | 1339 field->set_section(field->section() + "-cc"); |
1338 else | 1340 else |
1339 field->set_section(field->section() + "-default"); | 1341 field->set_section(field->section() + "-default"); |
1340 } | 1342 } |
1341 } | 1343 } |
1342 | 1344 |
1343 } // namespace autofill | 1345 } // namespace autofill |
OLD | NEW |