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 void ForEachMatchingFormFieldCommon( |
499 // the |callback| is invoked with the corresponding |form| field data. | 526 std::vector<WebFormControlElement>* control_elements, |
500 void ForEachMatchingFormField(const WebFormElement& form_element, | 527 const WebElement& initiating_element, |
501 const WebElement& initiating_element, | 528 const FormData& data, |
502 const FormData& data, | 529 FieldFilterMask filters, |
503 FieldFilterMask filters, | 530 bool force_override, |
504 bool force_override, | 531 Callback callback) { |
505 Callback callback) { | 532 DCHECK(control_elements); |
506 std::vector<WebFormControlElement> control_elements = | 533 if (control_elements->size() != data.fields.size()) { |
507 ExtractAutofillableElementsInForm(form_element, ExtractionRequirements()); | |
508 | |
509 if (control_elements.size() != data.fields.size()) { | |
510 // This case should be reachable only for pathological websites and tests, | 534 // 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 | 535 // which add or remove form fields while the user is interacting with the |
512 // Autofill popup. | 536 // Autofill popup. |
513 return; | 537 return; |
514 } | 538 } |
515 | 539 |
516 // It's possible that the site has injected fields into the form after the | 540 // 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 | 541 // 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 | 542 // 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 | 543 // 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. | 544 // are appended to the end of the form and are not visible. |
521 for (size_t i = 0; i < control_elements.size(); ++i) { | 545 for (size_t i = 0; i < control_elements->size(); ++i) { |
522 WebFormControlElement* element = &control_elements[i]; | 546 WebFormControlElement* element = &(*control_elements)[i]; |
523 | 547 |
524 if (base::string16(element->nameForAutofill()) != data.fields[i].name) { | 548 if (base::string16(element->nameForAutofill()) != data.fields[i].name) { |
525 // This case should be reachable only for pathological websites, which | 549 // This case should be reachable only for pathological websites, which |
526 // rename form fields while the user is interacting with the Autofill | 550 // 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 | 551 // popup. I (isherman) am not aware of any such websites, and so am |
528 // optimistically including a NOTREACHED(). If you ever trip this check, | 552 // optimistically including a NOTREACHED(). If you ever trip this check, |
529 // please file a bug against me. | 553 // please file a bug against me. |
530 NOTREACHED(); | 554 NOTREACHED(); |
531 continue; | 555 continue; |
532 } | 556 } |
(...skipping 11 matching lines...) Expand all Loading... |
544 | 568 |
545 if (((filters & FILTER_DISABLED_ELEMENTS) && !element->isEnabled()) || | 569 if (((filters & FILTER_DISABLED_ELEMENTS) && !element->isEnabled()) || |
546 ((filters & FILTER_READONLY_ELEMENTS) && element->isReadOnly()) || | 570 ((filters & FILTER_READONLY_ELEMENTS) && element->isReadOnly()) || |
547 ((filters & FILTER_NON_FOCUSABLE_ELEMENTS) && !element->isFocusable())) | 571 ((filters & FILTER_NON_FOCUSABLE_ELEMENTS) && !element->isFocusable())) |
548 continue; | 572 continue; |
549 | 573 |
550 callback(data.fields[i], is_initiating_element, element); | 574 callback(data.fields[i], is_initiating_element, element); |
551 } | 575 } |
552 } | 576 } |
553 | 577 |
| 578 // For each autofillable field in |data| that matches a field in the |form|, |
| 579 // the |callback| is invoked with the corresponding |form| field data. |
| 580 void ForEachMatchingFormField(const WebFormElement& form_element, |
| 581 const WebElement& initiating_element, |
| 582 const FormData& data, |
| 583 FieldFilterMask filters, |
| 584 bool force_override, |
| 585 Callback callback) { |
| 586 std::vector<WebFormControlElement> control_elements = |
| 587 ExtractAutofillableElementsInForm(form_element, ExtractionRequirements()); |
| 588 ForEachMatchingFormFieldCommon(&control_elements, initiating_element, data, |
| 589 filters, force_override, callback); |
| 590 } |
| 591 |
| 592 // For each autofillable field in |data| that matches a field in the set of |
| 593 // unowned autofillable form fields, the |callback| is invoked with the |
| 594 // corresponding |data| field. |
| 595 void ForEachMatchingUnownedFormField(const WebElement& initiating_element, |
| 596 const FormData& data, |
| 597 FieldFilterMask filters, |
| 598 bool force_override, |
| 599 Callback callback) { |
| 600 if (initiating_element.isNull()) |
| 601 return; |
| 602 |
| 603 std::vector<WebFormControlElement> control_elements = |
| 604 GetUnownedAutofillableFormFieldElements( |
| 605 initiating_element.document().all(), nullptr); |
| 606 if (!IsElementInControlElementSet(initiating_element, control_elements)) |
| 607 return; |
| 608 |
| 609 ForEachMatchingFormFieldCommon(&control_elements, initiating_element, data, |
| 610 filters, force_override, callback); |
| 611 } |
| 612 |
554 // Sets the |field|'s value to the value in |data|. | 613 // Sets the |field|'s value to the value in |data|. |
555 // Also sets the "autofilled" attribute, causing the background to be yellow. | 614 // Also sets the "autofilled" attribute, causing the background to be yellow. |
556 void FillFormField(const FormFieldData& data, | 615 void FillFormField(const FormFieldData& data, |
557 bool is_initiating_node, | 616 bool is_initiating_node, |
558 blink::WebFormControlElement* field) { | 617 blink::WebFormControlElement* field) { |
559 // Nothing to fill. | 618 // Nothing to fill. |
560 if (data.value.empty()) | 619 if (data.value.empty()) |
561 return; | 620 return; |
562 | 621 |
563 if (!data.is_autofilled) | 622 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 | 777 // Concatenate labels because some sites might have multiple label |
719 // candidates. | 778 // candidates. |
720 if (!iter->second->label.empty() && !label_text.empty()) | 779 if (!iter->second->label.empty() && !label_text.empty()) |
721 iter->second->label += base::ASCIIToUTF16(" "); | 780 iter->second->label += base::ASCIIToUTF16(" "); |
722 iter->second->label += label_text; | 781 iter->second->label += label_text; |
723 } | 782 } |
724 } | 783 } |
725 | 784 |
726 // Common function shared by WebFormElementToFormData() and | 785 // Common function shared by WebFormElementToFormData() and |
727 // UnownedFormElementsAndFieldSetsToFormData(). Either pass in: | 786 // UnownedFormElementsAndFieldSetsToFormData(). Either pass in: |
728 // 1) |form_element|, |form_control_element| and an empty |fieldsets|. | 787 // 1) |form_element| and an empty |fieldsets|. |
729 // or | 788 // or |
730 // 2) a non-empty |fieldsets|. | 789 // 2) a NULL |form_element|. |
| 790 // |
| 791 // If |field| is not NULL, then |form_control_element| should be not NULL. |
731 bool FormOrFieldsetsToFormData( | 792 bool FormOrFieldsetsToFormData( |
732 const blink::WebFormElement* form_element, | 793 const blink::WebFormElement* form_element, |
733 const blink::WebFormControlElement* form_control_element, | 794 const blink::WebFormControlElement* form_control_element, |
734 const std::vector<blink::WebElement>& fieldsets, | 795 const std::vector<blink::WebElement>& fieldsets, |
735 const WebVector<WebFormControlElement>& control_elements, | 796 const WebVector<WebFormControlElement>& control_elements, |
736 RequirementsMask requirements, | 797 RequirementsMask requirements, |
737 ExtractMask extract_mask, | 798 ExtractMask extract_mask, |
738 FormData* form, | 799 FormData* form, |
739 FormFieldData* field) { | 800 FormFieldData* field) { |
740 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); | 801 CR_DEFINE_STATIC_LOCAL(WebString, kLabel, ("label")); |
741 | 802 |
742 if (form_element) { | 803 if (form_element) |
| 804 DCHECK(fieldsets.empty()); |
| 805 if (field) |
743 DCHECK(form_control_element); | 806 DCHECK(form_control_element); |
744 DCHECK(fieldsets.empty()); | |
745 } else { | |
746 DCHECK(!form_control_element); | |
747 DCHECK(!field); | |
748 } | |
749 | 807 |
750 // A map from a FormFieldData's name to the FormFieldData itself. | 808 // A map from a FormFieldData's name to the FormFieldData itself. |
751 std::map<base::string16, FormFieldData*> name_map; | 809 std::map<base::string16, FormFieldData*> name_map; |
752 | 810 |
753 // The extracted FormFields. We use pointers so we can store them in | 811 // The extracted FormFields. We use pointers so we can store them in |
754 // |name_map|. | 812 // |name_map|. |
755 ScopedVector<FormFieldData> form_fields; | 813 ScopedVector<FormFieldData> form_fields; |
756 | 814 |
757 // A vector of bools that indicate whether each field in the form meets the | 815 // A vector of bools that indicate whether each field in the form meets the |
758 // requirements and thus will be in the resulting |form|. | 816 // requirements and thus will be in the resulting |form|. |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1012 | 1070 |
1013 WebVector<WebFormControlElement> control_elements; | 1071 WebVector<WebFormControlElement> control_elements; |
1014 form_element.getFormControlElements(control_elements); | 1072 form_element.getFormControlElements(control_elements); |
1015 | 1073 |
1016 std::vector<blink::WebElement> dummy_fieldset; | 1074 std::vector<blink::WebElement> dummy_fieldset; |
1017 return FormOrFieldsetsToFormData(&form_element, &form_control_element, | 1075 return FormOrFieldsetsToFormData(&form_element, &form_control_element, |
1018 dummy_fieldset, control_elements, | 1076 dummy_fieldset, control_elements, |
1019 requirements, extract_mask, form, field); | 1077 requirements, extract_mask, form, field); |
1020 } | 1078 } |
1021 | 1079 |
| 1080 std::vector<WebFormControlElement> |
| 1081 GetUnownedAutofillableFormFieldElements( |
| 1082 const WebElementCollection& elements, |
| 1083 std::vector<WebElement>* fieldsets) { |
| 1084 std::vector<WebFormControlElement> unowned_fieldset_children; |
| 1085 for (WebElement element = elements.firstItem(); |
| 1086 !element.isNull(); |
| 1087 element = elements.nextItem()) { |
| 1088 if (element.isFormControlElement()) { |
| 1089 WebFormControlElement control = element.to<WebFormControlElement>(); |
| 1090 if (control.form().isNull()) |
| 1091 unowned_fieldset_children.push_back(control); |
| 1092 } |
| 1093 |
| 1094 if (fieldsets && element.hasHTMLTagName("fieldset") && |
| 1095 !IsElementInsideFormOrFieldSet(element)) { |
| 1096 fieldsets->push_back(element); |
| 1097 } |
| 1098 } |
| 1099 return ExtractAutofillableElementsFromSet(unowned_fieldset_children, |
| 1100 REQUIRE_NONE); |
| 1101 } |
| 1102 |
1022 bool UnownedFormElementsAndFieldSetsToFormData( | 1103 bool UnownedFormElementsAndFieldSetsToFormData( |
1023 const std::vector<blink::WebElement>& fieldsets, | 1104 const std::vector<blink::WebElement>& fieldsets, |
1024 const std::vector<blink::WebFormControlElement>& control_elements, | 1105 const std::vector<blink::WebFormControlElement>& control_elements, |
| 1106 const blink::WebFormControlElement* element, |
1025 const GURL& origin, | 1107 const GURL& origin, |
| 1108 RequirementsMask requirements, |
1026 ExtractMask extract_mask, | 1109 ExtractMask extract_mask, |
1027 FormData* form) { | 1110 FormData* form, |
| 1111 FormFieldData* field) { |
1028 form->origin = origin; | 1112 form->origin = origin; |
1029 form->user_submitted = false; | 1113 form->user_submitted = false; |
1030 | 1114 |
1031 return FormOrFieldsetsToFormData(nullptr, nullptr, fieldsets, | 1115 return FormOrFieldsetsToFormData(nullptr, element, fieldsets, |
1032 control_elements, REQUIRE_NONE, extract_mask, | 1116 control_elements, requirements, extract_mask, |
1033 form, nullptr); | 1117 form, field); |
1034 } | 1118 } |
1035 | 1119 |
1036 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element, | 1120 bool FindFormAndFieldForFormControlElement(const WebFormControlElement& element, |
1037 FormData* form, | 1121 FormData* form, |
1038 FormFieldData* field, | 1122 FormFieldData* field, |
1039 RequirementsMask requirements) { | 1123 RequirementsMask requirements) { |
1040 if (!IsAutofillableElement(element)) | 1124 if (!IsAutofillableElement(element)) |
1041 return false; | 1125 return false; |
1042 | 1126 |
1043 const WebFormElement form_element = element.form(); | |
1044 if (form_element.isNull()) | |
1045 return false; | |
1046 | |
1047 ExtractMask extract_mask = | 1127 ExtractMask extract_mask = |
1048 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); | 1128 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); |
| 1129 const WebFormElement form_element = element.form(); |
| 1130 if (form_element.isNull()) { |
| 1131 // No associated form, try the synthetic form for unowned form elements. |
| 1132 WebDocument document = element.document(); |
| 1133 std::vector<WebElement> fieldsets; |
| 1134 std::vector<WebFormControlElement> control_elements = |
| 1135 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets); |
| 1136 return UnownedFormElementsAndFieldSetsToFormData( |
| 1137 fieldsets, control_elements, &element, document.url(), requirements, |
| 1138 extract_mask, form, field); |
| 1139 } |
| 1140 |
1049 return WebFormElementToFormData(form_element, | 1141 return WebFormElementToFormData(form_element, |
1050 element, | 1142 element, |
1051 requirements, | 1143 requirements, |
1052 extract_mask, | 1144 extract_mask, |
1053 form, | 1145 form, |
1054 field); | 1146 field); |
1055 } | 1147 } |
1056 | 1148 |
1057 void FillForm(const FormData& form, const WebFormControlElement& element) { | 1149 void FillForm(const FormData& form, const WebFormControlElement& element) { |
1058 WebFormElement form_element = element.form(); | 1150 WebFormElement form_element = element.form(); |
1059 if (form_element.isNull()) | 1151 if (form_element.isNull()) { |
| 1152 ForEachMatchingUnownedFormField(element, |
| 1153 form, |
| 1154 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
| 1155 false, /* dont force override */ |
| 1156 &FillFormField); |
1060 return; | 1157 return; |
| 1158 } |
1061 | 1159 |
1062 ForEachMatchingFormField(form_element, | 1160 ForEachMatchingFormField(form_element, |
1063 element, | 1161 element, |
1064 form, | 1162 form, |
1065 FILTER_ALL_NON_EDITABLE_ELEMENTS, | 1163 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
1066 false, /* dont force override */ | 1164 false, /* dont force override */ |
1067 &FillFormField); | 1165 &FillFormField); |
1068 } | 1166 } |
1069 | 1167 |
1070 void FillFormIncludingNonFocusableElements(const FormData& form_data, | 1168 void FillFormIncludingNonFocusableElements(const FormData& form_data, |
1071 const WebFormElement& form_element) { | 1169 const WebFormElement& form_element) { |
1072 if (form_element.isNull()) | 1170 if (form_element.isNull()) { |
| 1171 NOTREACHED(); |
1073 return; | 1172 return; |
| 1173 } |
1074 | 1174 |
1075 FieldFilterMask filter_mask = static_cast<FieldFilterMask>( | 1175 FieldFilterMask filter_mask = static_cast<FieldFilterMask>( |
1076 FILTER_DISABLED_ELEMENTS | FILTER_READONLY_ELEMENTS); | 1176 FILTER_DISABLED_ELEMENTS | FILTER_READONLY_ELEMENTS); |
1077 ForEachMatchingFormField(form_element, | 1177 ForEachMatchingFormField(form_element, |
1078 WebInputElement(), | 1178 WebInputElement(), |
1079 form_data, | 1179 form_data, |
1080 filter_mask, | 1180 filter_mask, |
1081 true, /* force override */ | 1181 true, /* force override */ |
1082 &FillFormField); | 1182 &FillFormField); |
1083 } | 1183 } |
1084 | 1184 |
1085 void PreviewForm(const FormData& form, const WebFormControlElement& element) { | 1185 void PreviewForm(const FormData& form, const WebFormControlElement& element) { |
1086 WebFormElement form_element = element.form(); | 1186 WebFormElement form_element = element.form(); |
1087 if (form_element.isNull()) | 1187 if (form_element.isNull()) { |
| 1188 ForEachMatchingUnownedFormField(element, |
| 1189 form, |
| 1190 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
| 1191 false, /* dont force override */ |
| 1192 &PreviewFormField); |
1088 return; | 1193 return; |
| 1194 } |
1089 | 1195 |
1090 ForEachMatchingFormField(form_element, | 1196 ForEachMatchingFormField(form_element, |
1091 element, | 1197 element, |
1092 form, | 1198 form, |
1093 FILTER_ALL_NON_EDITABLE_ELEMENTS, | 1199 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
1094 false, /* dont force override */ | 1200 false, /* dont force override */ |
1095 &PreviewFormField); | 1201 &PreviewFormField); |
1096 } | 1202 } |
1097 | 1203 |
1098 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, | 1204 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, |
1099 bool was_autofilled) { | 1205 bool was_autofilled) { |
1100 WebFormElement form_element = element.form(); | 1206 WebFormElement form_element = element.form(); |
1101 if (form_element.isNull()) | 1207 std::vector<WebFormControlElement> control_elements; |
1102 return false; | 1208 if (form_element.isNull()) { |
| 1209 control_elements = GetUnownedAutofillableFormFieldElements( |
| 1210 element.document().all(), nullptr); |
| 1211 if (!IsElementInControlElementSet(element, control_elements)) |
| 1212 return false; |
| 1213 } else { |
| 1214 control_elements = ExtractAutofillableElementsInForm( |
| 1215 form_element, ExtractionRequirements()); |
| 1216 } |
1103 | 1217 |
1104 std::vector<WebFormControlElement> control_elements = | |
1105 ExtractAutofillableElementsInForm(form_element, ExtractionRequirements()); | |
1106 for (size_t i = 0; i < control_elements.size(); ++i) { | 1218 for (size_t i = 0; i < control_elements.size(); ++i) { |
1107 // There might be unrelated elements in this form which have already been | 1219 // 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 | 1220 // 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 | 1221 // 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. | 1222 // want to reset the auto-filled status for fields that were previewed. |
1111 WebFormControlElement control_element = control_elements[i]; | 1223 WebFormControlElement control_element = control_elements[i]; |
1112 | 1224 |
1113 // Only text input, textarea and select elements can be previewed. | 1225 // Only text input, textarea and select elements can be previewed. |
1114 WebInputElement* input_element = toWebInputElement(&control_element); | 1226 WebInputElement* input_element = toWebInputElement(&control_element); |
1115 if (!IsTextInput(input_element) && | 1227 if (!IsTextInput(input_element) && |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1208 | 1320 |
1209 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { | 1321 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { |
1210 gfx::Rect bounding_box(element->boundsInViewportSpace()); | 1322 gfx::Rect bounding_box(element->boundsInViewportSpace()); |
1211 return gfx::RectF(bounding_box.x() * scale, | 1323 return gfx::RectF(bounding_box.x() * scale, |
1212 bounding_box.y() * scale, | 1324 bounding_box.y() * scale, |
1213 bounding_box.width() * scale, | 1325 bounding_box.width() * scale, |
1214 bounding_box.height() * scale); | 1326 bounding_box.height() * scale); |
1215 } | 1327 } |
1216 | 1328 |
1217 } // namespace autofill | 1329 } // namespace autofill |
OLD | NEW |