Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(81)

Side by Side Diff: components/autofill/core/browser/form_structure.cc

Issue 1411363003: [Autofill] Always show available data when encountering autocomplete attributes (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed mathp's comments Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698