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 <stdint.h> | 7 #include <stdint.h> |
8 | 8 |
9 #include <map> | 9 #include <map> |
10 #include <utility> | 10 #include <utility> |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
359 | 359 |
360 if (autocomplete_attribute_value == "tel-local-prefix") | 360 if (autocomplete_attribute_value == "tel-local-prefix") |
361 return HTML_TYPE_TEL_LOCAL_PREFIX; | 361 return HTML_TYPE_TEL_LOCAL_PREFIX; |
362 | 362 |
363 if (autocomplete_attribute_value == "tel-local-suffix") | 363 if (autocomplete_attribute_value == "tel-local-suffix") |
364 return HTML_TYPE_TEL_LOCAL_SUFFIX; | 364 return HTML_TYPE_TEL_LOCAL_SUFFIX; |
365 | 365 |
366 if (autocomplete_attribute_value == "email") | 366 if (autocomplete_attribute_value == "email") |
367 return HTML_TYPE_EMAIL; | 367 return HTML_TYPE_EMAIL; |
368 | 368 |
369 return HTML_TYPE_UNKNOWN; | 369 if (autocomplete_attribute_value == "") |
Mathieu
2016/01/13 01:03:20
this should probably be first in the function, bec
sebsg
2016/01/13 16:05:13
Absolutely, I should have thought of this. Thanks!
| |
370 return HTML_TYPE_UNSPECIFIED; | |
371 | |
372 return HTML_TYPE_UNRECOGNIZED; | |
370 } | 373 } |
371 | 374 |
372 std::string StripDigitsIfRequired(const base::string16& input) { | 375 std::string StripDigitsIfRequired(const base::string16& input) { |
373 std::string return_string = base::UTF16ToUTF8(input); | 376 std::string return_string = base::UTF16ToUTF8(input); |
374 | 377 |
375 re2::RE2::GlobalReplace(&return_string, re2::RE2(kIgnorePatternInFieldName), | 378 re2::RE2::GlobalReplace(&return_string, re2::RE2(kIgnorePatternInFieldName), |
376 std::string()); | 379 std::string()); |
377 return return_string; | 380 return return_string; |
378 } | 381 } |
379 | 382 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
419 FormStructure::~FormStructure() {} | 422 FormStructure::~FormStructure() {} |
420 | 423 |
421 void FormStructure::DetermineHeuristicTypes() { | 424 void FormStructure::DetermineHeuristicTypes() { |
422 // First, try to detect field types based on each field's |autocomplete| | 425 // 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 | 426 // 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 | 427 // autocomplete type hint, don't try to apply other heuristics to match fields |
425 // in this form. | 428 // in this form. |
426 if (!was_parsed_for_autocomplete_attributes_) | 429 if (!was_parsed_for_autocomplete_attributes_) |
427 ParseFieldTypesFromAutocompleteAttributes(); | 430 ParseFieldTypesFromAutocompleteAttributes(); |
428 | 431 |
429 if (!has_author_specified_types_) { | 432 if (active_field_count() >= kRequiredFieldsForPredictionRoutines) { |
430 ServerFieldTypeMap field_type_map; | 433 ServerFieldTypeMap field_type_map; |
431 FormField::ParseFormFields(fields_.get(), is_form_tag_, &field_type_map); | 434 FormField::ParseFormFields(fields_.get(), is_form_tag_, &field_type_map); |
432 for (size_t i = 0; i < field_count(); ++i) { | 435 for (size_t i = 0; i < field_count(); ++i) { |
433 AutofillField* field = fields_[i]; | 436 AutofillField* field = fields_[i]; |
434 ServerFieldTypeMap::iterator iter = | 437 ServerFieldTypeMap::iterator iter = |
435 field_type_map.find(field->unique_name()); | 438 field_type_map.find(field->unique_name()); |
436 if (iter != field_type_map.end()) | 439 if (iter != field_type_map.end()) |
437 field->set_heuristic_type(iter->second); | 440 field->set_heuristic_type(iter->second); |
438 } | 441 } |
439 } | 442 } |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
775 | 778 |
776 bool has_text_field = false; | 779 bool has_text_field = false; |
777 for (const AutofillField* it : *this) { | 780 for (const AutofillField* it : *this) { |
778 has_text_field |= it->form_control_type != "select-one"; | 781 has_text_field |= it->form_control_type != "select-one"; |
779 } | 782 } |
780 | 783 |
781 return has_text_field; | 784 return has_text_field; |
782 } | 785 } |
783 | 786 |
784 bool FormStructure::ShouldBeCrowdsourced() const { | 787 bool FormStructure::ShouldBeCrowdsourced() const { |
785 return (has_password_field_ || !has_author_specified_types_) && | 788 return (has_password_field_ || |
786 ShouldBeParsed(); | 789 active_field_count() >= kRequiredFieldsForPredictionRoutines) && |
790 ShouldBeParsed(); | |
787 } | 791 } |
788 | 792 |
789 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { | 793 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { |
790 // Map from field signatures to cached fields. | 794 // Map from field signatures to cached fields. |
791 std::map<std::string, const AutofillField*> cached_fields; | 795 std::map<std::string, const AutofillField*> cached_fields; |
792 for (size_t i = 0; i < cached_form.field_count(); ++i) { | 796 for (size_t i = 0; i < cached_form.field_count(); ++i) { |
793 const AutofillField* field = cached_form.field(i); | 797 const AutofillField* field = cached_form.field(i); |
794 cached_fields[field->FieldSignature()] = field; | 798 cached_fields[field->FieldSignature()] = field; |
795 } | 799 } |
796 | 800 |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1159 autocomplete_attribute, " ", base::KEEP_WHITESPACE, | 1163 autocomplete_attribute, " ", base::KEEP_WHITESPACE, |
1160 base::SPLIT_WANT_NONEMPTY); | 1164 base::SPLIT_WANT_NONEMPTY); |
1161 | 1165 |
1162 // The final token must be the field type. | 1166 // The final token must be the field type. |
1163 // If it is not one of the known types, abort. | 1167 // If it is not one of the known types, abort. |
1164 DCHECK(!tokens.empty()); | 1168 DCHECK(!tokens.empty()); |
1165 std::string field_type_token = tokens.back(); | 1169 std::string field_type_token = tokens.back(); |
1166 tokens.pop_back(); | 1170 tokens.pop_back(); |
1167 HtmlFieldType field_type = | 1171 HtmlFieldType field_type = |
1168 FieldTypeFromAutocompleteAttributeValue(field_type_token, *field); | 1172 FieldTypeFromAutocompleteAttributeValue(field_type_token, *field); |
1169 if (field_type == HTML_TYPE_UNKNOWN) | 1173 if (field_type == HTML_TYPE_UNSPECIFIED) |
Mathieu
2016/01/13 01:03:20
shouldn't we also "continue" if it's unrecognized?
sebsg
2016/01/13 16:05:13
No because if we continue, it's like we give up on
| |
1170 continue; | 1174 continue; |
1171 | 1175 |
1172 // The preceding token, if any, may be a type hint. | 1176 // The preceding token, if any, may be a type hint. |
1173 if (!tokens.empty() && IsContactTypeHint(tokens.back())) { | 1177 if (!tokens.empty() && IsContactTypeHint(tokens.back())) { |
1174 // If it is, it must match the field type; otherwise, abort. | 1178 // If it is, it must match the field type; otherwise, abort. |
1175 // Note that an invalid token invalidates the entire attribute value, even | 1179 // Note that an invalid token invalidates the entire attribute value, even |
1176 // if the other tokens are valid. | 1180 // if the other tokens are valid. |
1177 if (!ContactTypeHintMatchesFieldType(tokens.back(), field_type)) | 1181 if (!ContactTypeHintMatchesFieldType(tokens.back(), field_type)) |
1178 continue; | 1182 continue; |
1179 | 1183 |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1365 for (AutofillField* field : fields_) { | 1369 for (AutofillField* field : fields_) { |
1366 FieldTypeGroup field_type_group = field->Type().group(); | 1370 FieldTypeGroup field_type_group = field->Type().group(); |
1367 if (field_type_group == CREDIT_CARD) | 1371 if (field_type_group == CREDIT_CARD) |
1368 field->set_section(field->section() + "-cc"); | 1372 field->set_section(field->section() + "-cc"); |
1369 else | 1373 else |
1370 field->set_section(field->section() + "-default"); | 1374 field->set_section(field->section() + "-default"); |
1371 } | 1375 } |
1372 } | 1376 } |
1373 | 1377 |
1374 } // namespace autofill | 1378 } // namespace autofill |
OLD | NEW |