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

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

Issue 365783002: Autofill: don't require POST method. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: remove method_ member Created 6 years, 5 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 | Annotate | Revision Log
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 15 matching lines...) Expand all
26 #include "components/autofill/core/common/form_data.h" 26 #include "components/autofill/core/common/form_data.h"
27 #include "components/autofill/core/common/form_data_predictions.h" 27 #include "components/autofill/core/common/form_data_predictions.h"
28 #include "components/autofill/core/common/form_field_data.h" 28 #include "components/autofill/core/common/form_field_data.h"
29 #include "components/autofill/core/common/form_field_data_predictions.h" 29 #include "components/autofill/core/common/form_field_data_predictions.h"
30 #include "third_party/icu/source/i18n/unicode/regex.h" 30 #include "third_party/icu/source/i18n/unicode/regex.h"
31 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" 31 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h"
32 32
33 namespace autofill { 33 namespace autofill {
34 namespace { 34 namespace {
35 35
36 const char kFormMethodPost[] = "post";
37
38 // XML elements and attributes. 36 // XML elements and attributes.
39 const char kAttributeAutofillUsed[] = "autofillused"; 37 const char kAttributeAutofillUsed[] = "autofillused";
40 const char kAttributeAutofillType[] = "autofilltype"; 38 const char kAttributeAutofillType[] = "autofilltype";
41 const char kAttributeClientVersion[] = "clientversion"; 39 const char kAttributeClientVersion[] = "clientversion";
42 const char kAttributeDataPresent[] = "datapresent"; 40 const char kAttributeDataPresent[] = "datapresent";
43 const char kAttributeFieldID[] = "fieldid"; 41 const char kAttributeFieldID[] = "fieldid";
44 const char kAttributeFieldType[] = "fieldtype"; 42 const char kAttributeFieldType[] = "fieldtype";
45 const char kAttributeFormSignature[] = "formsignature"; 43 const char kAttributeFormSignature[] = "formsignature";
46 const char kAttributeName[] = "name"; 44 const char kAttributeName[] = "name";
47 const char kAttributeSignature[] = "signature"; 45 const char kAttributeSignature[] = "signature";
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
373 // Make sure to prepend the counter with a non-numeric digit so that we are 371 // Make sure to prepend the counter with a non-numeric digit so that we are
374 // guaranteed to avoid collisions. 372 // guaranteed to avoid collisions.
375 if (!unique_names.count(field->name)) 373 if (!unique_names.count(field->name))
376 unique_names[field->name] = 1; 374 unique_names[field->name] = 1;
377 else 375 else
378 ++unique_names[field->name]; 376 ++unique_names[field->name];
379 base::string16 unique_name = field->name + base::ASCIIToUTF16("_") + 377 base::string16 unique_name = field->name + base::ASCIIToUTF16("_") +
380 base::IntToString16(unique_names[field->name]); 378 base::IntToString16(unique_names[field->name]);
381 fields_.push_back(new AutofillField(*field, unique_name)); 379 fields_.push_back(new AutofillField(*field, unique_name));
382 } 380 }
383
384 std::string method = base::UTF16ToUTF8(form.method);
385 if (StringToLowerASCII(method) == kFormMethodPost) {
386 method_ = POST;
387 } else {
388 // Either the method is 'get', or we don't know. In this case we default
389 // to GET.
390 method_ = GET;
391 }
392 } 381 }
393 382
394 FormStructure::~FormStructure() {} 383 FormStructure::~FormStructure() {}
395 384
396 void FormStructure::DetermineHeuristicTypes( 385 void FormStructure::DetermineHeuristicTypes(
397 const AutofillMetrics& metric_logger) { 386 const AutofillMetrics& metric_logger) {
398 // First, try to detect field types based on each field's |autocomplete| 387 // First, try to detect field types based on each field's |autocomplete|
399 // attribute value. If there is at least one form field that specifies an 388 // attribute value. If there is at least one form field that specifies an
400 // autocomplete type hint, don't try to apply other heuristics to match fields 389 // autocomplete type hint, don't try to apply other heuristics to match fields
401 // in this form. 390 // in this form.
402 bool has_author_specified_sections; 391 bool has_author_specified_sections;
403 ParseFieldTypesFromAutocompleteAttributes(&has_author_specified_types_, 392 ParseFieldTypesFromAutocompleteAttributes(&has_author_specified_types_,
404 &has_author_specified_sections); 393 &has_author_specified_sections);
405 394
406 if (!has_author_specified_types_) { 395 if (!has_author_specified_types_) {
407 ServerFieldTypeMap field_type_map; 396 ServerFieldTypeMap field_type_map;
408 FormField::ParseFormFields(fields_.get(), &field_type_map); 397 FormField::ParseFormFields(fields_.get(), &field_type_map);
409 for (size_t i = 0; i < field_count(); ++i) { 398 for (size_t i = 0; i < field_count(); ++i) {
410 AutofillField* field = fields_[i]; 399 AutofillField* field = fields_[i];
411 ServerFieldTypeMap::iterator iter = 400 ServerFieldTypeMap::iterator iter =
412 field_type_map.find(field->unique_name()); 401 field_type_map.find(field->unique_name());
413 if (iter != field_type_map.end()) 402 if (iter != field_type_map.end())
414 field->set_heuristic_type(iter->second); 403 field->set_heuristic_type(iter->second);
415 } 404 }
416 } 405 }
417 406
418 UpdateAutofillCount(); 407 UpdateAutofillCount();
419 IdentifySections(has_author_specified_sections); 408 IdentifySections(has_author_specified_sections);
420 409
421 if (IsAutofillable(true)) { 410 if (IsAutofillable()) {
422 metric_logger.LogDeveloperEngagementMetric( 411 metric_logger.LogDeveloperEngagementMetric(
423 AutofillMetrics::FILLABLE_FORM_PARSED); 412 AutofillMetrics::FILLABLE_FORM_PARSED);
424 if (has_author_specified_types_) { 413 if (has_author_specified_types_) {
425 metric_logger.LogDeveloperEngagementMetric( 414 metric_logger.LogDeveloperEngagementMetric(
426 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS); 415 AutofillMetrics::FILLABLE_FORM_CONTAINS_TYPE_HINTS);
427 } 416 }
428 } 417 }
429 } 418 }
430 419
431 bool FormStructure::EncodeUploadRequest( 420 bool FormStructure::EncodeUploadRequest(
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
628 // static 617 // static
629 void FormStructure::GetFieldTypePredictions( 618 void FormStructure::GetFieldTypePredictions(
630 const std::vector<FormStructure*>& form_structures, 619 const std::vector<FormStructure*>& form_structures,
631 std::vector<FormDataPredictions>* forms) { 620 std::vector<FormDataPredictions>* forms) {
632 forms->clear(); 621 forms->clear();
633 forms->reserve(form_structures.size()); 622 forms->reserve(form_structures.size());
634 for (size_t i = 0; i < form_structures.size(); ++i) { 623 for (size_t i = 0; i < form_structures.size(); ++i) {
635 FormStructure* form_structure = form_structures[i]; 624 FormStructure* form_structure = form_structures[i];
636 FormDataPredictions form; 625 FormDataPredictions form;
637 form.data.name = form_structure->form_name_; 626 form.data.name = form_structure->form_name_;
638 form.data.method =
639 base::ASCIIToUTF16((form_structure->method_ == POST) ? "POST" : "GET");
640 form.data.origin = form_structure->source_url_; 627 form.data.origin = form_structure->source_url_;
641 form.data.action = form_structure->target_url_; 628 form.data.action = form_structure->target_url_;
642 form.signature = form_structure->FormSignature(); 629 form.signature = form_structure->FormSignature();
643 630
644 for (std::vector<AutofillField*>::const_iterator field = 631 for (std::vector<AutofillField*>::const_iterator field =
645 form_structure->fields_.begin(); 632 form_structure->fields_.begin();
646 field != form_structure->fields_.end(); ++field) { 633 field != form_structure->fields_.end(); ++field) {
647 form.data.fields.push_back(FormFieldData(**field)); 634 form.data.fields.push_back(FormFieldData(**field));
648 635
649 FormFieldDataPredictions annotated_field; 636 FormFieldDataPredictions annotated_field;
(...skipping 25 matching lines...) Expand all
675 base::UTF16ToUTF8(form_name_) + 662 base::UTF16ToUTF8(form_name_) +
676 form_signature_field_names_; 663 form_signature_field_names_;
677 664
678 return Hash64Bit(form_string); 665 return Hash64Bit(form_string);
679 } 666 }
680 667
681 bool FormStructure::ShouldSkipField(const FormFieldData& field) const { 668 bool FormStructure::ShouldSkipField(const FormFieldData& field) const {
682 return field.is_checkable; 669 return field.is_checkable;
683 } 670 }
684 671
685 bool FormStructure::IsAutofillable(bool require_method_post) const { 672 bool FormStructure::IsAutofillable() const {
686 if (autofill_count() < kRequiredAutofillFields) 673 if (autofill_count() < kRequiredAutofillFields)
687 return false; 674 return false;
688 675
689 return ShouldBeParsed(require_method_post); 676 return ShouldBeParsed();
690 } 677 }
691 678
692 void FormStructure::UpdateAutofillCount() { 679 void FormStructure::UpdateAutofillCount() {
693 autofill_count_ = 0; 680 autofill_count_ = 0;
694 for (std::vector<AutofillField*>::const_iterator iter = begin(); 681 for (std::vector<AutofillField*>::const_iterator iter = begin();
695 iter != end(); ++iter) { 682 iter != end(); ++iter) {
696 AutofillField* field = *iter; 683 AutofillField* field = *iter;
697 if (field && field->IsFieldFillable()) 684 if (field && field->IsFieldFillable())
698 ++autofill_count_; 685 ++autofill_count_;
699 } 686 }
700 } 687 }
701 688
702 bool FormStructure::ShouldBeParsed(bool require_method_post) const { 689 bool FormStructure::ShouldBeParsed() const {
703 if (active_field_count() < kRequiredAutofillFields) 690 if (active_field_count() < kRequiredAutofillFields)
704 return false; 691 return false;
705 692
706 // Rule out http(s)://*/search?... 693 // Rule out http(s)://*/search?...
707 // e.g. http://www.google.com/search?q=... 694 // e.g. http://www.google.com/search?q=...
708 // http://search.yahoo.com/search?p=... 695 // http://search.yahoo.com/search?p=...
709 if (target_url_.path() == "/search") 696 if (target_url_.path() == "/search")
710 return false; 697 return false;
711 698
712 bool has_text_field = false; 699 bool has_text_field = false;
713 for (std::vector<AutofillField*>::const_iterator it = begin(); 700 for (std::vector<AutofillField*>::const_iterator it = begin();
714 it != end() && !has_text_field; ++it) { 701 it != end() && !has_text_field; ++it) {
715 has_text_field |= (*it)->form_control_type != "select-one"; 702 has_text_field |= (*it)->form_control_type != "select-one";
716 } 703 }
717 if (!has_text_field)
718 return false;
719 704
720 return !require_method_post || (method_ == POST); 705 return has_text_field;
721 } 706 }
722 707
723 bool FormStructure::ShouldBeCrowdsourced() const { 708 bool FormStructure::ShouldBeCrowdsourced() const {
724 return !has_author_specified_types_ && ShouldBeParsed(true); 709 return !has_author_specified_types_ && ShouldBeParsed();
725 } 710 }
726 711
727 void FormStructure::UpdateFromCache(const FormStructure& cached_form) { 712 void FormStructure::UpdateFromCache(const FormStructure& cached_form) {
728 // Map from field signatures to cached fields. 713 // Map from field signatures to cached fields.
729 std::map<std::string, const AutofillField*> cached_fields; 714 std::map<std::string, const AutofillField*> cached_fields;
730 for (size_t i = 0; i < cached_form.field_count(); ++i) { 715 for (size_t i = 0; i < cached_form.field_count(); ++i) {
731 const AutofillField* field = cached_form.field(i); 716 const AutofillField* field = cached_form.field(i);
732 cached_fields[field->FieldSignature()] = field; 717 cached_fields[field->FieldSignature()] = field;
733 } 718 }
734 719
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 size_t FormStructure::active_field_count() const { 909 size_t FormStructure::active_field_count() const {
925 return active_field_count_; 910 return active_field_count_;
926 } 911 }
927 912
928 FormData FormStructure::ToFormData() const { 913 FormData FormStructure::ToFormData() const {
929 // |data.user_submitted| will always be false. 914 // |data.user_submitted| will always be false.
930 FormData data; 915 FormData data;
931 data.name = form_name_; 916 data.name = form_name_;
932 data.origin = source_url_; 917 data.origin = source_url_;
933 data.action = target_url_; 918 data.action = target_url_;
934 data.method = base::ASCIIToUTF16(method_ == POST ? "POST" : "GET");
935 919
936 for (size_t i = 0; i < fields_.size(); ++i) { 920 for (size_t i = 0; i < fields_.size(); ++i) {
937 data.fields.push_back(FormFieldData(*fields_[i])); 921 data.fields.push_back(FormFieldData(*fields_[i]));
938 } 922 }
939 923
940 return data; 924 return data;
941 } 925 }
942 926
943 bool FormStructure::operator==(const FormData& form) const { 927 bool FormStructure::operator==(const FormData& form) const {
944 // TODO(jhawkins): Is this enough to differentiate a form? 928 // TODO(jhawkins): Is this enough to differentiate a form?
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 field != fields_.end(); ++field) { 1226 field != fields_.end(); ++field) {
1243 FieldTypeGroup field_type_group = (*field)->Type().group(); 1227 FieldTypeGroup field_type_group = (*field)->Type().group();
1244 if (field_type_group == CREDIT_CARD) 1228 if (field_type_group == CREDIT_CARD)
1245 (*field)->set_section((*field)->section() + "-cc"); 1229 (*field)->set_section((*field)->section() + "-cc");
1246 else 1230 else
1247 (*field)->set_section((*field)->section() + "-default"); 1231 (*field)->set_section((*field)->section() + "-default");
1248 } 1232 }
1249 } 1233 }
1250 1234
1251 } // namespace autofill 1235 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/core/browser/form_structure.h ('k') | components/autofill/core/browser/form_structure_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698