| 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/content/renderer/form_autofill_util.h" | 5 #include "components/autofill/content/renderer/form_autofill_util.h" |
| 6 | 6 |
| 7 #include <map> | 7 #include <map> |
| 8 | 8 |
| 9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_vector.h" | 11 #include "base/memory/scoped_vector.h" |
| 12 #include "base/metrics/field_trial.h" | |
| 13 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
| 14 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 15 #include "components/autofill/core/common/autofill_data_validation.h" | 14 #include "components/autofill/core/common/autofill_data_validation.h" |
| 16 #include "components/autofill/core/common/autofill_switches.h" | 15 #include "components/autofill/core/common/autofill_switches.h" |
| 17 #include "components/autofill/core/common/form_data.h" | 16 #include "components/autofill/core/common/form_data.h" |
| 18 #include "components/autofill/core/common/form_field_data.h" | 17 #include "components/autofill/core/common/form_field_data.h" |
| 19 #include "third_party/WebKit/public/platform/WebString.h" | 18 #include "third_party/WebKit/public/platform/WebString.h" |
| 20 #include "third_party/WebKit/public/platform/WebVector.h" | 19 #include "third_party/WebKit/public/platform/WebVector.h" |
| 21 #include "third_party/WebKit/public/web/WebDocument.h" | 20 #include "third_party/WebKit/public/web/WebDocument.h" |
| 22 #include "third_party/WebKit/public/web/WebElement.h" | 21 #include "third_party/WebKit/public/web/WebElement.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 93 return node.isElementNode() && node.toConst<WebElement>().hasHTMLTagName(tag); | 92 return node.isElementNode() && node.toConst<WebElement>().hasHTMLTagName(tag); |
| 94 } | 93 } |
| 95 | 94 |
| 96 bool IsAutofillableElement(const WebFormControlElement& element) { | 95 bool IsAutofillableElement(const WebFormControlElement& element) { |
| 97 const WebInputElement* input_element = toWebInputElement(&element); | 96 const WebInputElement* input_element = toWebInputElement(&element); |
| 98 return IsAutofillableInputElement(input_element) || | 97 return IsAutofillableInputElement(input_element) || |
| 99 IsSelectElement(element) || | 98 IsSelectElement(element) || |
| 100 IsTextAreaElement(element); | 99 IsTextAreaElement(element); |
| 101 } | 100 } |
| 102 | 101 |
| 102 bool IsElementInControlElementSet( |
| 103 const WebElement& element, |
| 104 const std::vector<WebFormControlElement>& control_elements) { |
| 105 if (!element.isFormControlElement()) |
| 106 return false; |
| 107 const WebFormControlElement form_control_element = |
| 108 element.toConst<WebFormControlElement>(); |
| 109 return std::find(control_elements.begin(), |
| 110 control_elements.end(), |
| 111 form_control_element) != control_elements.end(); |
| 112 } |
| 113 |
| 114 bool IsElementInsideFormOrFieldSet(const WebElement& element) { |
| 115 for (WebNode parent_node = element.parentNode(); |
| 116 !parent_node.isNull(); |
| 117 parent_node = parent_node.parentNode()) { |
| 118 if (!parent_node.isElementNode()) |
| 119 continue; |
| 120 |
| 121 WebElement cur_element = parent_node.to<WebElement>(); |
| 122 if (cur_element.hasHTMLTagName("form") || |
| 123 cur_element.hasHTMLTagName("fieldset")) { |
| 124 return true; |
| 125 } |
| 126 } |
| 127 return false; |
| 128 } |
| 129 |
| 103 // Check whether the given field satisfies the REQUIRE_AUTOCOMPLETE requirement. | 130 // Check whether the given field satisfies the REQUIRE_AUTOCOMPLETE requirement. |
| 104 bool SatisfiesRequireAutocomplete(const WebInputElement& input_element) { | 131 bool SatisfiesRequireAutocomplete(const WebInputElement& input_element) { |
| 105 return input_element.autoComplete(); | 132 return input_element.autoComplete(); |
| 106 } | 133 } |
| 107 | 134 |
| 108 // Appends |suffix| to |prefix| so that any intermediary whitespace is collapsed | 135 // Appends |suffix| to |prefix| so that any intermediary whitespace is collapsed |
| 109 // to a single space. If |force_whitespace| is true, then the resulting string | 136 // to a single space. If |force_whitespace| is true, then the resulting string |
| 110 // is guaranteed to have a space between |prefix| and |suffix|. Otherwise, the | 137 // is guaranteed to have a space between |prefix| and |suffix|. Otherwise, the |
| 111 // result includes a space only if |prefix| has trailing whitespace or |suffix| | 138 // result includes a space only if |prefix| has trailing whitespace or |suffix| |
| 112 // has leading whitespace. | 139 // has leading whitespace. |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 488 option_contents->push_back(option.text()); | 515 option_contents->push_back(option.text()); |
| 489 } | 516 } |
| 490 } | 517 } |
| 491 } | 518 } |
| 492 | 519 |
| 493 // The callback type used by |ForEachMatchingFormField()|. | 520 // The callback type used by |ForEachMatchingFormField()|. |
| 494 typedef void (*Callback)(const FormFieldData&, | 521 typedef void (*Callback)(const FormFieldData&, |
| 495 bool, /* is_initiating_element */ | 522 bool, /* is_initiating_element */ |
| 496 blink::WebFormControlElement*); | 523 blink::WebFormControlElement*); |
| 497 | 524 |
| 498 // For each autofillable field in |data| that matches a field in the |form|, | 525 // Common code shared by ForEachMatchingFormField() and |
| 499 // the |callback| is invoked with the corresponding |form| field data. | 526 // ForEachMatchingUnownedFormField(). |
| 500 void ForEachMatchingFormField(const WebFormElement& form_element, | 527 void ForEachMatchingFormFieldCommon( |
| 501 const WebElement& initiating_element, | 528 std::vector<WebFormControlElement>* control_elements, |
| 502 const FormData& data, | 529 const WebElement& initiating_element, |
| 503 FieldFilterMask filters, | 530 const FormData& data, |
| 504 bool force_override, | 531 FieldFilterMask filters, |
| 505 Callback callback) { | 532 bool force_override, |
| 506 std::vector<WebFormControlElement> control_elements = | 533 Callback callback) { |
| 507 ExtractAutofillableElementsInForm(form_element, ExtractionRequirements()); | 534 DCHECK(control_elements); |
| 508 | 535 if (control_elements->size() != data.fields.size()) { |
| 509 if (control_elements.size() != data.fields.size()) { | |
| 510 // This case should be reachable only for pathological websites and tests, | 536 // This case should be reachable only for pathological websites and tests, |
| 511 // which add or remove form fields while the user is interacting with the | 537 // which add or remove form fields while the user is interacting with the |
| 512 // Autofill popup. | 538 // Autofill popup. |
| 513 return; | 539 return; |
| 514 } | 540 } |
| 515 | 541 |
| 516 // It's possible that the site has injected fields into the form after the | 542 // It's possible that the site has injected fields into the form after the |
| 517 // page has loaded, so we can't assert that the size of the cached control | 543 // page has loaded, so we can't assert that the size of the cached control |
| 518 // elements is equal to the size of the fields in |form|. Fortunately, the | 544 // elements is equal to the size of the fields in |form|. Fortunately, the |
| 519 // one case in the wild where this happens, paypal.com signup form, the fields | 545 // one case in the wild where this happens, paypal.com signup form, the fields |
| 520 // are appended to the end of the form and are not visible. | 546 // are appended to the end of the form and are not visible. |
| 521 for (size_t i = 0; i < control_elements.size(); ++i) { | 547 for (size_t i = 0; i < control_elements->size(); ++i) { |
| 522 WebFormControlElement* element = &control_elements[i]; | 548 WebFormControlElement* element = &(*control_elements)[i]; |
| 523 | 549 |
| 524 if (base::string16(element->nameForAutofill()) != data.fields[i].name) { | 550 if (base::string16(element->nameForAutofill()) != data.fields[i].name) { |
| 525 // This case should be reachable only for pathological websites, which | 551 // This case should be reachable only for pathological websites, which |
| 526 // rename form fields while the user is interacting with the Autofill | 552 // rename form fields while the user is interacting with the Autofill |
| 527 // popup. I (isherman) am not aware of any such websites, and so am | 553 // popup. I (isherman) am not aware of any such websites, and so am |
| 528 // optimistically including a NOTREACHED(). If you ever trip this check, | 554 // optimistically including a NOTREACHED(). If you ever trip this check, |
| 529 // please file a bug against me. | 555 // please file a bug against me. |
| 530 NOTREACHED(); | 556 NOTREACHED(); |
| 531 continue; | 557 continue; |
| 532 } | 558 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 544 | 570 |
| 545 if (((filters & FILTER_DISABLED_ELEMENTS) && !element->isEnabled()) || | 571 if (((filters & FILTER_DISABLED_ELEMENTS) && !element->isEnabled()) || |
| 546 ((filters & FILTER_READONLY_ELEMENTS) && element->isReadOnly()) || | 572 ((filters & FILTER_READONLY_ELEMENTS) && element->isReadOnly()) || |
| 547 ((filters & FILTER_NON_FOCUSABLE_ELEMENTS) && !element->isFocusable())) | 573 ((filters & FILTER_NON_FOCUSABLE_ELEMENTS) && !element->isFocusable())) |
| 548 continue; | 574 continue; |
| 549 | 575 |
| 550 callback(data.fields[i], is_initiating_element, element); | 576 callback(data.fields[i], is_initiating_element, element); |
| 551 } | 577 } |
| 552 } | 578 } |
| 553 | 579 |
| 580 // For each autofillable field in |data| that matches a field in the |form|, |
| 581 // the |callback| is invoked with the corresponding |form| field data. |
| 582 void ForEachMatchingFormField(const WebFormElement& form_element, |
| 583 const WebElement& initiating_element, |
| 584 const FormData& data, |
| 585 FieldFilterMask filters, |
| 586 bool force_override, |
| 587 Callback callback) { |
| 588 std::vector<WebFormControlElement> control_elements = |
| 589 ExtractAutofillableElementsInForm(form_element, ExtractionRequirements()); |
| 590 ForEachMatchingFormFieldCommon(&control_elements, initiating_element, data, |
| 591 filters, force_override, callback); |
| 592 } |
| 593 |
| 594 // For each autofillable field in |data| that matches a field in the set of |
| 595 // unowned autofillable form fields, the |callback| is invoked with the |
| 596 // corresponding |data| field. |
| 597 void ForEachMatchingUnownedFormField(const WebElement& initiating_element, |
| 598 const FormData& data, |
| 599 FieldFilterMask filters, |
| 600 bool force_override, |
| 601 Callback callback) { |
| 602 if (initiating_element.isNull()) |
| 603 return; |
| 604 |
| 605 std::vector<WebFormControlElement> control_elements = |
| 606 GetUnownedAutofillableFormFieldElements( |
| 607 initiating_element.document().all(), nullptr); |
| 608 if (!IsElementInControlElementSet(initiating_element, control_elements)) |
| 609 return; |
| 610 |
| 611 ForEachMatchingFormFieldCommon(&control_elements, initiating_element, data, |
| 612 filters, force_override, callback); |
| 613 } |
| 614 |
| 554 // Sets the |field|'s value to the value in |data|. | 615 // Sets the |field|'s value to the value in |data|. |
| 555 // Also sets the "autofilled" attribute, causing the background to be yellow. | 616 // Also sets the "autofilled" attribute, causing the background to be yellow. |
| 556 void FillFormField(const FormFieldData& data, | 617 void FillFormField(const FormFieldData& data, |
| 557 bool is_initiating_node, | 618 bool is_initiating_node, |
| 558 blink::WebFormControlElement* field) { | 619 blink::WebFormControlElement* field) { |
| 559 // Nothing to fill. | 620 // Nothing to fill. |
| 560 if (data.value.empty()) | 621 if (data.value.empty()) |
| 561 return; | 622 return; |
| 562 | 623 |
| 563 if (!data.is_autofilled) | 624 if (!data.is_autofilled) |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 718 // Concatenate labels because some sites might have multiple label | 779 // Concatenate labels because some sites might have multiple label |
| 719 // candidates. | 780 // candidates. |
| 720 if (!iter->second->label.empty() && !label_text.empty()) | 781 if (!iter->second->label.empty() && !label_text.empty()) |
| 721 iter->second->label += base::ASCIIToUTF16(" "); | 782 iter->second->label += base::ASCIIToUTF16(" "); |
| 722 iter->second->label += label_text; | 783 iter->second->label += label_text; |
| 723 } | 784 } |
| 724 } | 785 } |
| 725 | 786 |
| 726 // Common function shared by WebFormElementToFormData() and | 787 // Common function shared by WebFormElementToFormData() and |
| 727 // UnownedFormElementsAndFieldSetsToFormData(). Either pass in: | 788 // UnownedFormElementsAndFieldSetsToFormData(). Either pass in: |
| 728 // 1) |form_element|, |form_control_element| and an empty |fieldsets|. | 789 // 1) |form_element| and an empty |fieldsets|. |
| 729 // or | 790 // or |
| 730 // 2) a non-empty |fieldsets|. | 791 // 2) a NULL |form_element|. |
| 792 // |
| 793 // If |field| is not NULL, then |form_control_element| should be not NULL. |
| 731 bool FormOrFieldsetsToFormData( | 794 bool FormOrFieldsetsToFormData( |
| 732 const blink::WebFormElement* form_element, | 795 const blink::WebFormElement* form_element, |
| 733 const blink::WebFormControlElement* form_control_element, | 796 const blink::WebFormControlElement* form_control_element, |
| 734 const std::vector<blink::WebElement>& fieldsets, | 797 const std::vector<blink::WebElement>& fieldsets, |
| 735 const WebVector<WebFormControlElement>& control_elements, | 798 const WebVector<WebFormControlElement>& control_elements, |
| 736 RequirementsMask requirements, | 799 RequirementsMask requirements, |
| 737 ExtractMask extract_mask, | 800 ExtractMask extract_mask, |
| 738 FormData* form, | 801 FormData* form, |
| 739 FormFieldData* field) { | 802 FormFieldData* field) { |
| 740 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); | 803 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); |
| 741 | 804 |
| 742 if (form_element) { | 805 if (form_element) |
| 806 DCHECK(fieldsets.empty()); |
| 807 if (field) |
| 743 DCHECK(form_control_element); | 808 DCHECK(form_control_element); |
| 744 DCHECK(fieldsets.empty()); | |
| 745 } else { | |
| 746 DCHECK(!form_control_element); | |
| 747 DCHECK(!field); | |
| 748 } | |
| 749 | 809 |
| 750 // A map from a FormFieldData's name to the FormFieldData itself. | 810 // A map from a FormFieldData's name to the FormFieldData itself. |
| 751 std::map<base::string16, FormFieldData*> name_map; | 811 std::map<base::string16, FormFieldData*> name_map; |
| 752 | 812 |
| 753 // The extracted FormFields. We use pointers so we can store them in | 813 // The extracted FormFields. We use pointers so we can store them in |
| 754 // |name_map|. | 814 // |name_map|. |
| 755 ScopedVector<FormFieldData> form_fields; | 815 ScopedVector<FormFieldData> form_fields; |
| 756 | 816 |
| 757 // A vector of bools that indicate whether each field in the form meets the | 817 // A vector of bools that indicate whether each field in the form meets the |
| 758 // requirements and thus will be in the resulting |form|. | 818 // requirements and thus will be in the resulting |form|. |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 | 1072 |
| 1013 WebVector<WebFormControlElement> control_elements; | 1073 WebVector<WebFormControlElement> control_elements; |
| 1014 form_element.getFormControlElements(control_elements); | 1074 form_element.getFormControlElements(control_elements); |
| 1015 | 1075 |
| 1016 std::vector<blink::WebElement> dummy_fieldset; | 1076 std::vector<blink::WebElement> dummy_fieldset; |
| 1017 return FormOrFieldsetsToFormData(&form_element, &form_control_element, | 1077 return FormOrFieldsetsToFormData(&form_element, &form_control_element, |
| 1018 dummy_fieldset, control_elements, | 1078 dummy_fieldset, control_elements, |
| 1019 requirements, extract_mask, form, field); | 1079 requirements, extract_mask, form, field); |
| 1020 } | 1080 } |
| 1021 | 1081 |
| 1082 std::vector<WebFormControlElement> |
| 1083 GetUnownedAutofillableFormFieldElements( |
| 1084 const WebElementCollection& elements, |
| 1085 std::vector<WebElement>* fieldsets) { |
| 1086 std::vector<WebFormControlElement> unowned_fieldset_children; |
| 1087 for (WebElement element = elements.firstItem(); |
| 1088 !element.isNull(); |
| 1089 element = elements.nextItem()) { |
| 1090 if (element.isFormControlElement()) { |
| 1091 WebFormControlElement control = element.to<WebFormControlElement>(); |
| 1092 if (control.form().isNull()) |
| 1093 unowned_fieldset_children.push_back(control); |
| 1094 } |
| 1095 |
| 1096 if (fieldsets && element.hasHTMLTagName("fieldset") && |
| 1097 !IsElementInsideFormOrFieldSet(element)) { |
| 1098 fieldsets->push_back(element); |
| 1099 } |
| 1100 } |
| 1101 return ExtractAutofillableElementsFromSet(unowned_fieldset_children, |
| 1102 REQUIRE_NONE); |
| 1103 } |
| 1104 |
| 1022 bool UnownedFormElementsAndFieldSetsToFormData( | 1105 bool UnownedFormElementsAndFieldSetsToFormData( |
| 1023 const std::vector<blink::WebElement>& fieldsets, | 1106 const std::vector<blink::WebElement>& fieldsets, |
| 1024 const std::vector<blink::WebFormControlElement>& control_elements, | 1107 const std::vector<blink::WebFormControlElement>& control_elements, |
| 1108 const blink::WebFormControlElement* element, |
| 1025 const GURL& origin, | 1109 const GURL& origin, |
| 1110 RequirementsMask requirements, |
| 1026 ExtractMask extract_mask, | 1111 ExtractMask extract_mask, |
| 1027 FormData* form) { | 1112 FormData* form, |
| 1113 FormFieldData* field) { |
| 1028 form->origin = origin; | 1114 form->origin = origin; |
| 1029 form->user_submitted = false; | 1115 form->user_submitted = false; |
| 1030 | 1116 |
| 1031 return FormOrFieldsetsToFormData(nullptr, nullptr, fieldsets, | 1117 return FormOrFieldsetsToFormData(nullptr, element, fieldsets, |
| 1032 control_elements, REQUIRE_NONE, extract_mask, | 1118 control_elements, requirements, extract_mask, |
| 1033 form, nullptr); | 1119 form, field); |
| 1034 } | 1120 } |
| 1035 | 1121 |
| 1036 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element, | 1122 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element, |
| 1037 FormData* form, | 1123 FormData* form, |
| 1038 FormFieldData* field, | 1124 FormFieldData* field, |
| 1039 RequirementsMask requirements) { | 1125 RequirementsMask requirements) { |
| 1040 if (!IsAutofillableElement(element)) | 1126 if (!IsAutofillableElement(element)) |
| 1041 return false; | 1127 return false; |
| 1042 | 1128 |
| 1043 const WebFormElement form_element = element.form(); | 1129 const WebFormElement form_element = element.form(); |
| 1044 if (form_element.isNull()) | 1130 if (form_element.isNull()) |
| 1045 return false; | 1131 return false; |
| 1046 | 1132 |
| 1047 ExtractMask extract_mask = | 1133 ExtractMask extract_mask = |
| 1048 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); | 1134 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); |
| 1049 return WebFormElementToFormData(form_element, | 1135 return WebFormElementToFormData(form_element, |
| 1050 element, | 1136 element, |
| 1051 requirements, | 1137 requirements, |
| 1052 extract_mask, | 1138 extract_mask, |
| 1053 form, | 1139 form, |
| 1054 field); | 1140 field); |
| 1055 } | 1141 } |
| 1056 | 1142 |
| 1057 void FillForm(const FormData& form, const WebFormControlElement& element) { | 1143 void FillForm(const FormData& form, const WebFormControlElement& element) { |
| 1058 WebFormElement form_element = element.form(); | 1144 WebFormElement form_element = element.form(); |
| 1059 if (form_element.isNull()) | 1145 if (form_element.isNull()) { |
| 1146 ForEachMatchingUnownedFormField(element, |
| 1147 form, |
| 1148 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
| 1149 false, /* dont force override */ |
| 1150 &FillFormField); |
| 1060 return; | 1151 return; |
| 1152 } |
| 1061 | 1153 |
| 1062 ForEachMatchingFormField(form_element, | 1154 ForEachMatchingFormField(form_element, |
| 1063 element, | 1155 element, |
| 1064 form, | 1156 form, |
| 1065 FILTER_ALL_NON_EDITABLE_ELEMENTS, | 1157 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
| 1066 false, /* dont force override */ | 1158 false, /* dont force override */ |
| 1067 &FillFormField); | 1159 &FillFormField); |
| 1068 } | 1160 } |
| 1069 | 1161 |
| 1070 void FillFormIncludingNonFocusableElements(const FormData& form_data, | 1162 void FillFormIncludingNonFocusableElements(const FormData& form_data, |
| 1071 const WebFormElement& form_element) { | 1163 const WebFormElement& form_element) { |
| 1072 if (form_element.isNull()) | 1164 if (form_element.isNull()) { |
| 1165 NOTREACHED(); |
| 1073 return; | 1166 return; |
| 1167 } |
| 1074 | 1168 |
| 1075 FieldFilterMask filter_mask = static_cast<FieldFilterMask>( | 1169 FieldFilterMask filter_mask = static_cast<FieldFilterMask>( |
| 1076 FILTER_DISABLED_ELEMENTS | FILTER_READONLY_ELEMENTS); | 1170 FILTER_DISABLED_ELEMENTS | FILTER_READONLY_ELEMENTS); |
| 1077 ForEachMatchingFormField(form_element, | 1171 ForEachMatchingFormField(form_element, |
| 1078 WebInputElement(), | 1172 WebInputElement(), |
| 1079 form_data, | 1173 form_data, |
| 1080 filter_mask, | 1174 filter_mask, |
| 1081 true, /* force override */ | 1175 true, /* force override */ |
| 1082 &FillFormField); | 1176 &FillFormField); |
| 1083 } | 1177 } |
| 1084 | 1178 |
| 1085 void PreviewForm(const FormData& form, const WebFormControlElement& element) { | 1179 void PreviewForm(const FormData& form, const WebFormControlElement& element) { |
| 1086 WebFormElement form_element = element.form(); | 1180 WebFormElement form_element = element.form(); |
| 1087 if (form_element.isNull()) | 1181 if (form_element.isNull()) { |
| 1182 ForEachMatchingUnownedFormField(element, |
| 1183 form, |
| 1184 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
| 1185 false, /* dont force override */ |
| 1186 &PreviewFormField); |
| 1088 return; | 1187 return; |
| 1188 } |
| 1089 | 1189 |
| 1090 ForEachMatchingFormField(form_element, | 1190 ForEachMatchingFormField(form_element, |
| 1091 element, | 1191 element, |
| 1092 form, | 1192 form, |
| 1093 FILTER_ALL_NON_EDITABLE_ELEMENTS, | 1193 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
| 1094 false, /* dont force override */ | 1194 false, /* dont force override */ |
| 1095 &PreviewFormField); | 1195 &PreviewFormField); |
| 1096 } | 1196 } |
| 1097 | 1197 |
| 1098 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, | 1198 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, |
| 1099 bool was_autofilled) { | 1199 bool was_autofilled) { |
| 1100 WebFormElement form_element = element.form(); | 1200 WebFormElement form_element = element.form(); |
| 1101 if (form_element.isNull()) | 1201 std::vector<WebFormControlElement> control_elements; |
| 1102 return false; | 1202 if (form_element.isNull()) { |
| 1203 control_elements = GetUnownedAutofillableFormFieldElements( |
| 1204 element.document().all(), nullptr); |
| 1205 if (!IsElementInControlElementSet(element, control_elements)) |
| 1206 return false; |
| 1207 } else { |
| 1208 control_elements = ExtractAutofillableElementsInForm( |
| 1209 form_element, ExtractionRequirements()); |
| 1210 } |
| 1103 | 1211 |
| 1104 std::vector<WebFormControlElement> control_elements = | |
| 1105 ExtractAutofillableElementsInForm(form_element, ExtractionRequirements()); | |
| 1106 for (size_t i = 0; i < control_elements.size(); ++i) { | 1212 for (size_t i = 0; i < control_elements.size(); ++i) { |
| 1107 // There might be unrelated elements in this form which have already been | 1213 // There might be unrelated elements in this form which have already been |
| 1108 // auto-filled. For example, the user might have already filled the address | 1214 // auto-filled. For example, the user might have already filled the address |
| 1109 // part of a form and now be dealing with the credit card section. We only | 1215 // part of a form and now be dealing with the credit card section. We only |
| 1110 // want to reset the auto-filled status for fields that were previewed. | 1216 // want to reset the auto-filled status for fields that were previewed. |
| 1111 WebFormControlElement control_element = control_elements[i]; | 1217 WebFormControlElement control_element = control_elements[i]; |
| 1112 | 1218 |
| 1113 // Only text input, textarea and select elements can be previewed. | 1219 // Only text input, textarea and select elements can be previewed. |
| 1114 WebInputElement* input_element = toWebInputElement(&control_element); | 1220 WebInputElement* input_element = toWebInputElement(&control_element); |
| 1115 if (!IsTextInput(input_element) && | 1221 if (!IsTextInput(input_element) && |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1208 | 1314 |
| 1209 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { | 1315 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { |
| 1210 gfx::Rect bounding_box(element->boundsInViewportSpace()); | 1316 gfx::Rect bounding_box(element->boundsInViewportSpace()); |
| 1211 return gfx::RectF(bounding_box.x() * scale, | 1317 return gfx::RectF(bounding_box.x() * scale, |
| 1212 bounding_box.y() * scale, | 1318 bounding_box.y() * scale, |
| 1213 bounding_box.width() * scale, | 1319 bounding_box.width() * scale, |
| 1214 bounding_box.height() * scale); | 1320 bounding_box.height() * scale); |
| 1215 } | 1321 } |
| 1216 | 1322 |
| 1217 } // namespace autofill | 1323 } // namespace autofill |
| OLD | NEW |