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

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

Issue 2609703002: Remove ScopedVector from autofill. (Closed)
Patch Set: drop the using Created 3 years, 11 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 <stdint.h> 7 #include <stdint.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <map> 10 #include <map>
11 #include <utility> 11 #include <utility>
12 12
13 #include "base/command_line.h" 13 #include "base/command_line.h"
14 #include "base/i18n/case_conversion.h" 14 #include "base/i18n/case_conversion.h"
15 #include "base/logging.h" 15 #include "base/logging.h"
16 #include "base/memory/ptr_util.h"
16 #include "base/metrics/field_trial.h" 17 #include "base/metrics/field_trial.h"
17 #include "base/sha1.h" 18 #include "base/sha1.h"
18 #include "base/strings/string_number_conversions.h" 19 #include "base/strings/string_number_conversions.h"
19 #include "base/strings/string_split.h" 20 #include "base/strings/string_split.h"
20 #include "base/strings/string_util.h" 21 #include "base/strings/string_util.h"
21 #include "base/strings/stringprintf.h" 22 #include "base/strings/stringprintf.h"
22 #include "base/strings/utf_string_conversions.h" 23 #include "base/strings/utf_string_conversions.h"
23 #include "base/time/time.h" 24 #include "base/time/time.h"
24 #include "components/autofill/core/browser/autofill_metrics.h" 25 #include "components/autofill/core/browser/autofill_metrics.h"
25 #include "components/autofill/core/browser/autofill_type.h" 26 #include "components/autofill/core/browser/autofill_type.h"
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 has_password_field_ = true; 315 has_password_field_ = true;
315 else 316 else
316 all_fields_are_passwords_ = false; 317 all_fields_are_passwords_ = false;
317 318
318 // Generate a unique name for this field by appending a counter to the name. 319 // Generate a unique name for this field by appending a counter to the name.
319 // Make sure to prepend the counter with a non-numeric digit so that we are 320 // Make sure to prepend the counter with a non-numeric digit so that we are
320 // guaranteed to avoid collisions. 321 // guaranteed to avoid collisions.
321 base::string16 unique_name = 322 base::string16 unique_name =
322 field.name + base::ASCIIToUTF16("_") + 323 field.name + base::ASCIIToUTF16("_") +
323 base::SizeTToString16(++unique_names[field.name]); 324 base::SizeTToString16(++unique_names[field.name]);
324 fields_.push_back(new AutofillField(field, unique_name)); 325 fields_.push_back(base::MakeUnique<AutofillField>(field, unique_name));
325 } 326 }
326 327
327 form_signature_ = autofill::CalculateFormSignature(form); 328 form_signature_ = autofill::CalculateFormSignature(form);
328 // Do further processing on the fields, as needed. 329 // Do further processing on the fields, as needed.
329 ProcessExtractedFields(); 330 ProcessExtractedFields();
330 } 331 }
331 332
332 FormStructure::~FormStructure() {} 333 FormStructure::~FormStructure() {}
333 334
334 void FormStructure::DetermineHeuristicTypes() { 335 void FormStructure::DetermineHeuristicTypes() {
335 const auto determine_heuristic_types_start_time = base::TimeTicks::Now(); 336 const auto determine_heuristic_types_start_time = base::TimeTicks::Now();
336 337
337 // First, try to detect field types based on each field's |autocomplete| 338 // First, try to detect field types based on each field's |autocomplete|
338 // attribute value. 339 // attribute value.
339 if (!was_parsed_for_autocomplete_attributes_) 340 if (!was_parsed_for_autocomplete_attributes_)
340 ParseFieldTypesFromAutocompleteAttributes(); 341 ParseFieldTypesFromAutocompleteAttributes();
341 342
342 // Then if there are enough active fields, and if we are dealing with either a 343 // Then if there are enough active fields, and if we are dealing with either a
343 // proper <form> or a <form>-less checkout, run the heuristics and server 344 // proper <form> or a <form>-less checkout, run the heuristics and server
344 // prediction routines. 345 // prediction routines.
345 if (active_field_count() >= kRequiredFieldsForPredictionRoutines && 346 if (active_field_count() >= kRequiredFieldsForPredictionRoutines &&
346 (is_form_tag_ || is_formless_checkout_)) { 347 (is_form_tag_ || is_formless_checkout_)) {
347 const FieldCandidatesMap field_type_map = 348 const FieldCandidatesMap field_type_map =
348 FormField::ParseFormFields(fields_.get(), is_form_tag_); 349 FormField::ParseFormFields(fields_, is_form_tag_);
349 for (AutofillField* field : fields_) { 350 for (const auto& field : fields_) {
350 const auto iter = field_type_map.find(field->unique_name()); 351 const auto iter = field_type_map.find(field->unique_name());
351 if (iter != field_type_map.end()) 352 if (iter != field_type_map.end())
352 field->set_heuristic_type(iter->second.BestHeuristicType()); 353 field->set_heuristic_type(iter->second.BestHeuristicType());
353 } 354 }
354 } 355 }
355 356
356 UpdateAutofillCount(); 357 UpdateAutofillCount();
357 IdentifySections(has_author_specified_sections_); 358 IdentifySections(has_author_specified_sections_);
358 359
359 if (IsAutofillable()) { 360 if (IsAutofillable()) {
(...skipping 12 matching lines...) Expand all
372 bool FormStructure::EncodeUploadRequest( 373 bool FormStructure::EncodeUploadRequest(
373 const ServerFieldTypeSet& available_field_types, 374 const ServerFieldTypeSet& available_field_types,
374 bool form_was_autofilled, 375 bool form_was_autofilled,
375 const std::string& login_form_signature, 376 const std::string& login_form_signature,
376 bool observed_submission, 377 bool observed_submission,
377 AutofillUploadContents* upload) const { 378 AutofillUploadContents* upload) const {
378 DCHECK(ShouldBeCrowdsourced()); 379 DCHECK(ShouldBeCrowdsourced());
379 380
380 // Verify that |available_field_types| agrees with the possible field types we 381 // Verify that |available_field_types| agrees with the possible field types we
381 // are uploading. 382 // are uploading.
382 for (const AutofillField* field : *this) { 383 for (const auto& field : *this) {
383 for (const auto& type : field->possible_types()) { 384 for (const auto& type : field->possible_types()) {
384 DCHECK(type == UNKNOWN_TYPE || type == EMPTY_TYPE || 385 DCHECK(type == UNKNOWN_TYPE || type == EMPTY_TYPE ||
385 available_field_types.count(type)); 386 available_field_types.count(type));
386 } 387 }
387 } 388 }
388 389
389 upload->set_submission(observed_submission); 390 upload->set_submission(observed_submission);
390 upload->set_client_version(kClientVersion); 391 upload->set_client_version(kClientVersion);
391 upload->set_form_signature(form_signature()); 392 upload->set_form_signature(form_signature());
392 upload->set_autofill_used(form_was_autofilled); 393 upload->set_autofill_used(form_was_autofilled);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 bool heuristics_detected_fillable_field = false; 462 bool heuristics_detected_fillable_field = false;
462 bool query_response_overrode_heuristics = false; 463 bool query_response_overrode_heuristics = false;
463 464
464 // Copy the field types into the actual form. 465 // Copy the field types into the actual form.
465 auto current_field = response.field().begin(); 466 auto current_field = response.field().begin();
466 for (FormStructure* form : forms) { 467 for (FormStructure* form : forms) {
467 form->upload_required_ = 468 form->upload_required_ =
468 response.upload_required() ? UPLOAD_REQUIRED : UPLOAD_NOT_REQUIRED; 469 response.upload_required() ? UPLOAD_REQUIRED : UPLOAD_NOT_REQUIRED;
469 470
470 bool query_response_has_no_server_data = true; 471 bool query_response_has_no_server_data = true;
471 for (AutofillField* field : form->fields_) { 472 for (auto& field : form->fields_) {
472 if (form->ShouldSkipField(*field)) 473 if (form->ShouldSkipField(*field))
473 continue; 474 continue;
474 475
475 // In some cases *successful* response does not return all the fields. 476 // In some cases *successful* response does not return all the fields.
476 // Quit the update of the types then. 477 // Quit the update of the types then.
477 if (current_field == response.field().end()) 478 if (current_field == response.field().end())
478 break; 479 break;
479 480
480 ServerFieldType field_type = 481 ServerFieldType field_type =
481 static_cast<ServerFieldType>(current_field->autofill_type()); 482 static_cast<ServerFieldType>(current_field->autofill_type());
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 std::vector<FormDataPredictions> forms; 527 std::vector<FormDataPredictions> forms;
527 forms.reserve(form_structures.size()); 528 forms.reserve(form_structures.size());
528 for (const FormStructure* form_structure : form_structures) { 529 for (const FormStructure* form_structure : form_structures) {
529 FormDataPredictions form; 530 FormDataPredictions form;
530 form.data.name = form_structure->form_name_; 531 form.data.name = form_structure->form_name_;
531 form.data.origin = form_structure->source_url_; 532 form.data.origin = form_structure->source_url_;
532 form.data.action = form_structure->target_url_; 533 form.data.action = form_structure->target_url_;
533 form.data.is_form_tag = form_structure->is_form_tag_; 534 form.data.is_form_tag = form_structure->is_form_tag_;
534 form.signature = form_structure->FormSignatureAsStr(); 535 form.signature = form_structure->FormSignatureAsStr();
535 536
536 for (const AutofillField* field : form_structure->fields_) { 537 for (const auto& field : form_structure->fields_) {
537 form.data.fields.push_back(FormFieldData(*field)); 538 form.data.fields.push_back(FormFieldData(*field));
538 539
539 FormFieldDataPredictions annotated_field; 540 FormFieldDataPredictions annotated_field;
540 annotated_field.signature = field->FieldSignatureAsStr(); 541 annotated_field.signature = field->FieldSignatureAsStr();
541 annotated_field.heuristic_type = 542 annotated_field.heuristic_type =
542 AutofillType(field->heuristic_type()).ToString(); 543 AutofillType(field->heuristic_type()).ToString();
543 annotated_field.server_type = 544 annotated_field.server_type =
544 AutofillType(field->server_type()).ToString(); 545 AutofillType(field->server_type()).ToString();
545 annotated_field.overall_type = field->Type().ToString(); 546 annotated_field.overall_type = field->Type().ToString();
546 annotated_field.parseable_name = 547 annotated_field.parseable_name =
(...skipping 20 matching lines...) Expand all
567 bool FormStructure::IsAutofillable() const { 568 bool FormStructure::IsAutofillable() const {
568 if (autofill_count() < kRequiredFieldsForPredictionRoutines) 569 if (autofill_count() < kRequiredFieldsForPredictionRoutines)
569 return false; 570 return false;
570 571
571 return ShouldBeParsed(); 572 return ShouldBeParsed();
572 } 573 }
573 574
574 bool FormStructure::IsCompleteCreditCardForm() const { 575 bool FormStructure::IsCompleteCreditCardForm() const {
575 bool found_cc_number = false; 576 bool found_cc_number = false;
576 bool found_cc_expiration = false; 577 bool found_cc_expiration = false;
577 for (const AutofillField* field : fields_) { 578 for (const auto& field : fields_) {
578 ServerFieldType type = field->Type().GetStorableType(); 579 ServerFieldType type = field->Type().GetStorableType();
579 if (!found_cc_expiration && IsCreditCardExpirationType(type)) { 580 if (!found_cc_expiration && IsCreditCardExpirationType(type)) {
580 found_cc_expiration = true; 581 found_cc_expiration = true;
581 } else if (!found_cc_number && type == CREDIT_CARD_NUMBER) { 582 } else if (!found_cc_number && type == CREDIT_CARD_NUMBER) {
582 found_cc_number = true; 583 found_cc_number = true;
583 } 584 }
584 if (found_cc_expiration && found_cc_number) 585 if (found_cc_expiration && found_cc_number)
585 return true; 586 return true;
586 } 587 }
587 return false; 588 return false;
588 } 589 }
589 590
590 void FormStructure::UpdateAutofillCount() { 591 void FormStructure::UpdateAutofillCount() {
591 autofill_count_ = 0; 592 autofill_count_ = 0;
592 for (const AutofillField* field : *this) { 593 for (const auto& field : *this) {
593 if (field && field->IsFieldFillable()) 594 if (field && field->IsFieldFillable())
594 ++autofill_count_; 595 ++autofill_count_;
595 } 596 }
596 } 597 }
597 598
598 bool FormStructure::ShouldBeParsed() const { 599 bool FormStructure::ShouldBeParsed() const {
599 if (active_field_count() < kRequiredFieldsForPredictionRoutines && 600 if (active_field_count() < kRequiredFieldsForPredictionRoutines &&
600 (!all_fields_are_passwords() || 601 (!all_fields_are_passwords() ||
601 active_field_count() < kRequiredFieldsForFormsWithOnlyPasswordFields) && 602 active_field_count() < kRequiredFieldsForFormsWithOnlyPasswordFields) &&
602 !has_author_specified_types_) { 603 !has_author_specified_types_) {
603 return false; 604 return false;
604 } 605 }
605 606
606 // Rule out http(s)://*/search?... 607 // Rule out http(s)://*/search?...
607 // e.g. http://www.google.com/search?q=... 608 // e.g. http://www.google.com/search?q=...
608 // http://search.yahoo.com/search?p=... 609 // http://search.yahoo.com/search?p=...
609 if (target_url_.path_piece() == "/search") 610 if (target_url_.path_piece() == "/search")
610 return false; 611 return false;
611 612
612 bool has_text_field = false; 613 bool has_text_field = false;
613 for (const AutofillField* it : *this) { 614 for (const auto& it : *this) {
614 has_text_field |= it->form_control_type != "select-one"; 615 has_text_field |= it->form_control_type != "select-one";
615 } 616 }
616 617
617 return has_text_field; 618 return has_text_field;
618 } 619 }
619 620
620 bool FormStructure::ShouldBeCrowdsourced() const { 621 bool FormStructure::ShouldBeCrowdsourced() const {
621 return (has_password_field_ || 622 return (has_password_field_ ||
622 active_field_count() >= kRequiredFieldsForPredictionRoutines) && 623 active_field_count() >= kRequiredFieldsForPredictionRoutines) &&
623 ShouldBeParsed(); 624 ShouldBeParsed();
624 } 625 }
625 626
626 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { 627 void FormStructure::UpdateFromCache(const FormStructure& cached_form) {
627 // Map from field signatures to cached fields. 628 // Map from field signatures to cached fields.
628 std::map<std::string, const AutofillField*> cached_fields; 629 std::map<std::string, const AutofillField*> cached_fields;
629 for (size_t i = 0; i < cached_form.field_count(); ++i) { 630 for (size_t i = 0; i < cached_form.field_count(); ++i) {
630 const AutofillField* field = cached_form.field(i); 631 const auto& field = cached_form.field(i);
631 cached_fields[field->FieldSignatureAsStr()] = field; 632 cached_fields[field->FieldSignatureAsStr()] = field;
632 } 633 }
633 634
634 for (AutofillField* field : *this) { 635 for (auto& field : *this) {
635 std::map<std::string, const AutofillField*>::const_iterator cached_field = 636 std::map<std::string, const AutofillField*>::const_iterator cached_field =
636 cached_fields.find(field->FieldSignatureAsStr()); 637 cached_fields.find(field->FieldSignatureAsStr());
637 if (cached_field != cached_fields.end()) { 638 if (cached_field != cached_fields.end()) {
638 if (field->form_control_type != "select-one" && 639 if (field->form_control_type != "select-one" &&
639 field->value == cached_field->second->value) { 640 field->value == cached_field->second->value) {
640 // From the perspective of learning user data, text fields containing 641 // From the perspective of learning user data, text fields containing
641 // default values are equivalent to empty fields. 642 // default values are equivalent to empty fields.
642 field->value = base::string16(); 643 field->value = base::string16();
643 } 644 }
644 645
(...skipping 28 matching lines...) Expand all
673 rappor::RapporServiceImpl* rappor_service, 674 rappor::RapporServiceImpl* rappor_service,
674 bool did_show_suggestions, 675 bool did_show_suggestions,
675 bool observed_submission) const { 676 bool observed_submission) const {
676 size_t num_detected_field_types = 0; 677 size_t num_detected_field_types = 0;
677 size_t num_server_mismatches = 0; 678 size_t num_server_mismatches = 0;
678 size_t num_heuristic_mismatches = 0; 679 size_t num_heuristic_mismatches = 0;
679 size_t num_edited_autofilled_fields = 0; 680 size_t num_edited_autofilled_fields = 0;
680 bool did_autofill_all_possible_fields = true; 681 bool did_autofill_all_possible_fields = true;
681 bool did_autofill_some_possible_fields = false; 682 bool did_autofill_some_possible_fields = false;
682 for (size_t i = 0; i < field_count(); ++i) { 683 for (size_t i = 0; i < field_count(); ++i) {
683 const AutofillField* field = this->field(i); 684 const auto& field = this->field(i);
684 685
685 // No further logging for password fields. Those are primarily related to a 686 // No further logging for password fields. Those are primarily related to a
686 // different feature code path, and so make more sense to track outside of 687 // different feature code path, and so make more sense to track outside of
687 // this metric. 688 // this metric.
688 if (field->form_control_type == "password") 689 if (field->form_control_type == "password")
689 continue; 690 continue;
690 691
691 // We count fields that were autofilled but later modified, regardless of 692 // We count fields that were autofilled but later modified, regardless of
692 // whether the data now in the field is recognized. 693 // whether the data now in the field is recognized.
693 if (field->previously_autofilled()) 694 if (field->previously_autofilled())
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 } else { 840 } else {
840 AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill( 841 AutofillMetrics::LogFormFillDurationFromInteractionWithoutAutofill(
841 elapsed); 842 elapsed);
842 } 843 }
843 } 844 }
844 } 845 }
845 } 846 }
846 } 847 }
847 848
848 void FormStructure::LogQualityMetricsBasedOnAutocomplete() const { 849 void FormStructure::LogQualityMetricsBasedOnAutocomplete() const {
849 for (const AutofillField* field : fields_) { 850 for (const auto& field : fields_) {
850 if (field->html_type() != HTML_TYPE_UNSPECIFIED && 851 if (field->html_type() != HTML_TYPE_UNSPECIFIED &&
851 field->html_type() != HTML_TYPE_UNRECOGNIZED) { 852 field->html_type() != HTML_TYPE_UNRECOGNIZED) {
852 // The type inferred by the autocomplete attribute. 853 // The type inferred by the autocomplete attribute.
853 AutofillType type(field->html_type(), field->html_mode()); 854 AutofillType type(field->html_type(), field->html_mode());
854 ServerFieldType actual_field_type = type.GetStorableType(); 855 ServerFieldType actual_field_type = type.GetStorableType();
855 856
856 const AutofillMetrics::QualityMetricType metric_type = 857 const AutofillMetrics::QualityMetricType metric_type =
857 AutofillMetrics::TYPE_AUTOCOMPLETE_BASED; 858 AutofillMetrics::TYPE_AUTOCOMPLETE_BASED;
858 // Log the quality of our heuristics predictions. 859 // Log the quality of our heuristics predictions.
859 if (field->heuristic_type() == UNKNOWN_TYPE) { 860 if (field->heuristic_type() == UNKNOWN_TYPE) {
(...skipping 20 matching lines...) Expand all
880 } 881 }
881 } 882 }
882 } 883 }
883 } 884 }
884 885
885 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() { 886 void FormStructure::ParseFieldTypesFromAutocompleteAttributes() {
886 const std::string kDefaultSection = "-default"; 887 const std::string kDefaultSection = "-default";
887 888
888 has_author_specified_types_ = false; 889 has_author_specified_types_ = false;
889 has_author_specified_sections_ = false; 890 has_author_specified_sections_ = false;
890 for (AutofillField* field : fields_) { 891 for (const auto& field : fields_) {
891 // To prevent potential section name collisions, add a default suffix for 892 // To prevent potential section name collisions, add a default suffix for
892 // other fields. Without this, 'autocomplete' attribute values 893 // other fields. Without this, 'autocomplete' attribute values
893 // "section--shipping street-address" and "shipping street-address" would be 894 // "section--shipping street-address" and "shipping street-address" would be
894 // parsed identically, given the section handling code below. We do this 895 // parsed identically, given the section handling code below. We do this
895 // before any validation so that fields with invalid attributes still end up 896 // before any validation so that fields with invalid attributes still end up
896 // in the default section. These default section names will be overridden 897 // in the default section. These default section names will be overridden
897 // by subsequent heuristic parsing steps if there are no author-specified 898 // by subsequent heuristic parsing steps if there are no author-specified
898 // section names. 899 // section names.
899 field->set_section(kDefaultSection); 900 field->set_section(kDefaultSection);
900 901
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 break; 1001 break;
1001 } 1002 }
1002 } 1003 }
1003 } 1004 }
1004 return filled_something; 1005 return filled_something;
1005 } 1006 }
1006 1007
1007 std::set<base::string16> FormStructure::PossibleValues(ServerFieldType type) { 1008 std::set<base::string16> FormStructure::PossibleValues(ServerFieldType type) {
1008 std::set<base::string16> values; 1009 std::set<base::string16> values;
1009 AutofillType target_type(type); 1010 AutofillType target_type(type);
1010 for (const AutofillField* field : fields_) { 1011 for (const auto& field : fields_) {
1011 if (field->Type().GetStorableType() != target_type.GetStorableType() || 1012 if (field->Type().GetStorableType() != target_type.GetStorableType() ||
1012 field->Type().group() != target_type.group()) { 1013 field->Type().group() != target_type.group()) {
1013 continue; 1014 continue;
1014 } 1015 }
1015 1016
1016 // No option values; anything goes. 1017 // No option values; anything goes.
1017 if (field->option_values.empty()) { 1018 if (field->option_values.empty()) {
1018 values.clear(); 1019 values.clear();
1019 break; 1020 break;
1020 } 1021 }
1021 1022
1022 for (const base::string16& val : field->option_values) { 1023 for (const base::string16& val : field->option_values) {
1023 if (!val.empty()) 1024 if (!val.empty())
1024 values.insert(base::i18n::ToUpper(val)); 1025 values.insert(base::i18n::ToUpper(val));
1025 } 1026 }
1026 1027
1027 for (const base::string16& content : field->option_contents) { 1028 for (const base::string16& content : field->option_contents) {
1028 if (!content.empty()) 1029 if (!content.empty())
1029 values.insert(base::i18n::ToUpper(content)); 1030 values.insert(base::i18n::ToUpper(content));
1030 } 1031 }
1031 } 1032 }
1032 1033
1033 return values; 1034 return values;
1034 } 1035 }
1035 1036
1036 base::string16 FormStructure::GetUniqueValue(HtmlFieldType type) const { 1037 base::string16 FormStructure::GetUniqueValue(HtmlFieldType type) const {
1037 base::string16 value; 1038 base::string16 value;
1038 for (const AutofillField* field : fields_) { 1039 for (const auto& field : fields_) {
1039 if (field->html_type() != type) 1040 if (field->html_type() != type)
1040 continue; 1041 continue;
1041 1042
1042 // More than one value found; abort rather than choosing one arbitrarily. 1043 // More than one value found; abort rather than choosing one arbitrarily.
1043 if (!value.empty() && !field->value.empty()) { 1044 if (!value.empty() && !field->value.empty()) {
1044 value.clear(); 1045 value.clear();
1045 break; 1046 break;
1046 } 1047 }
1047 1048
1048 value = field->value; 1049 value = field->value;
1049 } 1050 }
1050 1051
1051 return value; 1052 return value;
1052 } 1053 }
1053 1054
1054 const AutofillField* FormStructure::field(size_t index) const { 1055 const AutofillField* FormStructure::field(size_t index) const {
1055 if (index >= fields_.size()) { 1056 if (index >= fields_.size()) {
1056 NOTREACHED(); 1057 NOTREACHED();
1057 return NULL; 1058 return NULL;
1058 } 1059 }
1059 1060
1060 return fields_[index]; 1061 return fields_[index].get();
1061 } 1062 }
1062 1063
1063 AutofillField* FormStructure::field(size_t index) { 1064 AutofillField* FormStructure::field(size_t index) {
1064 return const_cast<AutofillField*>( 1065 return const_cast<AutofillField*>(
1065 static_cast<const FormStructure*>(this)->field(index)); 1066 static_cast<const FormStructure*>(this)->field(index));
1066 } 1067 }
1067 1068
1068 size_t FormStructure::field_count() const { 1069 size_t FormStructure::field_count() const {
1069 return fields_.size(); 1070 return fields_.size();
1070 } 1071 }
(...skipping 30 matching lines...) Expand all
1101 1102
1102 bool FormStructure::operator!=(const FormData& form) const { 1103 bool FormStructure::operator!=(const FormData& form) const {
1103 return !operator==(form); 1104 return !operator==(form);
1104 } 1105 }
1105 1106
1106 void FormStructure::EncodeFormForQuery( 1107 void FormStructure::EncodeFormForQuery(
1107 AutofillQueryContents::Form* query_form) const { 1108 AutofillQueryContents::Form* query_form) const {
1108 DCHECK(!IsMalformed()); 1109 DCHECK(!IsMalformed());
1109 1110
1110 query_form->set_signature(form_signature()); 1111 query_form->set_signature(form_signature());
1111 for (const AutofillField* field : fields_) { 1112 for (const auto& field : fields_) {
1112 if (ShouldSkipField(*field)) 1113 if (ShouldSkipField(*field))
1113 continue; 1114 continue;
1114 1115
1115 AutofillQueryContents::Form::Field* added_field = query_form->add_field(); 1116 AutofillQueryContents::Form::Field* added_field = query_form->add_field();
1116 1117
1117 added_field->set_signature(field->GetFieldSignature()); 1118 added_field->set_signature(field->GetFieldSignature());
1118 1119
1119 if (IsAutofillFieldMetadataEnabled()) { 1120 if (IsAutofillFieldMetadataEnabled()) {
1120 added_field->set_type(field->form_control_type); 1121 added_field->set_type(field->form_control_type);
1121 1122
1122 if (!field->name.empty()) 1123 if (!field->name.empty())
1123 added_field->set_name(base::UTF16ToUTF8(field->name)); 1124 added_field->set_name(base::UTF16ToUTF8(field->name));
1124 1125
1125 } 1126 }
1126 } 1127 }
1127 } 1128 }
1128 1129
1129 void FormStructure::EncodeFormForUpload(AutofillUploadContents* upload) const { 1130 void FormStructure::EncodeFormForUpload(AutofillUploadContents* upload) const {
1130 DCHECK(!IsMalformed()); 1131 DCHECK(!IsMalformed());
1131 1132
1132 for (const AutofillField* field : fields_) { 1133 for (const auto& field : fields_) {
1133 // Don't upload checkable fields. 1134 // Don't upload checkable fields.
1134 if (IsCheckable(field->check_status)) 1135 if (IsCheckable(field->check_status))
1135 continue; 1136 continue;
1136 1137
1137 const ServerFieldTypeSet& types = field->possible_types(); 1138 const ServerFieldTypeSet& types = field->possible_types();
1138 for (const auto& field_type : types) { 1139 for (const auto& field_type : types) {
1139 // Add the same field elements as the query and a few more below. 1140 // Add the same field elements as the query and a few more below.
1140 if (ShouldSkipField(*field)) 1141 if (ShouldSkipField(*field))
1141 continue; 1142 continue;
1142 1143
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1190 return; 1191 return;
1191 1192
1192 if (!has_author_specified_sections) { 1193 if (!has_author_specified_sections) {
1193 // Name sections after the first field in the section. 1194 // Name sections after the first field in the section.
1194 base::string16 current_section = fields_.front()->unique_name(); 1195 base::string16 current_section = fields_.front()->unique_name();
1195 1196
1196 // Keep track of the types we've seen in this section. 1197 // Keep track of the types we've seen in this section.
1197 std::set<ServerFieldType> seen_types; 1198 std::set<ServerFieldType> seen_types;
1198 ServerFieldType previous_type = UNKNOWN_TYPE; 1199 ServerFieldType previous_type = UNKNOWN_TYPE;
1199 1200
1200 for (AutofillField* field : fields_) { 1201 for (const auto& field : fields_) {
1201 const ServerFieldType current_type = field->Type().GetStorableType(); 1202 const ServerFieldType current_type = field->Type().GetStorableType();
1202 1203
1203 bool already_saw_current_type = seen_types.count(current_type) > 0; 1204 bool already_saw_current_type = seen_types.count(current_type) > 0;
1204 1205
1205 // Forms often ask for multiple phone numbers -- e.g. both a daytime and 1206 // Forms often ask for multiple phone numbers -- e.g. both a daytime and
1206 // evening phone number. Our phone number detection is also generally a 1207 // evening phone number. Our phone number detection is also generally a
1207 // little off. Hence, ignore this field type as a signal here. 1208 // little off. Hence, ignore this field type as a signal here.
1208 if (AutofillType(current_type).group() == PHONE_HOME) 1209 if (AutofillType(current_type).group() == PHONE_HOME)
1209 already_saw_current_type = false; 1210 already_saw_current_type = false;
1210 1211
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 seen_types.insert(current_type); 1245 seen_types.insert(current_type);
1245 previous_type = current_type; 1246 previous_type = current_type;
1246 } 1247 }
1247 1248
1248 field->set_section(base::UTF16ToUTF8(current_section)); 1249 field->set_section(base::UTF16ToUTF8(current_section));
1249 } 1250 }
1250 } 1251 }
1251 1252
1252 // Ensure that credit card and address fields are in separate sections. 1253 // Ensure that credit card and address fields are in separate sections.
1253 // This simplifies the section-aware logic in autofill_manager.cc. 1254 // This simplifies the section-aware logic in autofill_manager.cc.
1254 for (AutofillField* field : fields_) { 1255 for (const auto& field : fields_) {
1255 FieldTypeGroup field_type_group = field->Type().group(); 1256 FieldTypeGroup field_type_group = field->Type().group();
1256 if (field_type_group == CREDIT_CARD) 1257 if (field_type_group == CREDIT_CARD)
1257 field->set_section(field->section() + "-cc"); 1258 field->set_section(field->section() + "-cc");
1258 else 1259 else
1259 field->set_section(field->section() + "-default"); 1260 field->set_section(field->section() + "-default");
1260 } 1261 }
1261 } 1262 }
1262 1263
1263 bool FormStructure::ShouldSkipField(const FormFieldData& field) const { 1264 bool FormStructure::ShouldSkipField(const FormFieldData& field) const {
1264 return IsCheckable(field.check_status); 1265 return IsCheckable(field.check_status);
1265 } 1266 }
1266 1267
1267 void FormStructure::ProcessExtractedFields() { 1268 void FormStructure::ProcessExtractedFields() {
1268 // Update the field name parsed by heuristics if several criteria are met. 1269 // Update the field name parsed by heuristics if several criteria are met.
1269 // Several fields must be present in the form. 1270 // Several fields must be present in the form.
1270 if (field_count() < kCommonNamePrefixRemovalFieldThreshold) 1271 if (field_count() < kCommonNamePrefixRemovalFieldThreshold)
1271 return; 1272 return;
1272 1273
1273 // Find the longest common prefix within all the field names. 1274 // Find the longest common prefix within all the field names.
1274 std::vector<base::string16> names; 1275 std::vector<base::string16> names;
1275 names.reserve(field_count()); 1276 names.reserve(field_count());
1276 for (const AutofillField* field : *this) 1277 for (const auto& field : *this)
1277 names.push_back(field->name); 1278 names.push_back(field->name);
1278 1279
1279 const base::string16 longest_prefix = FindLongestCommonPrefix(names); 1280 const base::string16 longest_prefix = FindLongestCommonPrefix(names);
1280 if (longest_prefix.size() < kMinCommonNamePrefixLength) 1281 if (longest_prefix.size() < kMinCommonNamePrefixLength)
1281 return; 1282 return;
1282 1283
1283 // The name without the prefix will be used for heuristics parsing. 1284 // The name without the prefix will be used for heuristics parsing.
1284 for (AutofillField* field : *this) { 1285 for (auto& field : *this) {
1285 if (field->name.size() > longest_prefix.size()) { 1286 if (field->name.size() > longest_prefix.size()) {
1286 field->set_parseable_name( 1287 field->set_parseable_name(
1287 field->name.substr(longest_prefix.size(), field->name.size())); 1288 field->name.substr(longest_prefix.size(), field->name.size()));
1288 } 1289 }
1289 } 1290 }
1290 } 1291 }
1291 1292
1292 // static 1293 // static
1293 base::string16 FormStructure::FindLongestCommonPrefix( 1294 base::string16 FormStructure::FindLongestCommonPrefix(
1294 const std::vector<base::string16>& strings) { 1295 const std::vector<base::string16>& strings) {
(...skipping 21 matching lines...) Expand all
1316 filtered_strings[0].at(prefix_len)) { 1317 filtered_strings[0].at(prefix_len)) {
1317 // Mismatch found. 1318 // Mismatch found.
1318 return filtered_strings[i].substr(0, prefix_len); 1319 return filtered_strings[i].substr(0, prefix_len);
1319 } 1320 }
1320 } 1321 }
1321 } 1322 }
1322 return filtered_strings[0]; 1323 return filtered_strings[0];
1323 } 1324 }
1324 1325
1325 } // namespace autofill 1326 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/form_structure.h ('k') | components/autofill/core/browser/name_field_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698