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(). |
Evan Stade
2014/12/12 23:05:53
this documentation isn't necessary imo
Lei Zhang
2014/12/12 23:11:17
Done.
| |
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(); | |
1044 if (form_element.isNull()) | |
1045 return false; | |
1046 | |
1047 ExtractMask extract_mask = | 1129 ExtractMask extract_mask = |
1048 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); | 1130 static_cast<ExtractMask>(EXTRACT_VALUE | EXTRACT_OPTIONS); |
1131 const WebFormElement form_element = element.form(); | |
1132 if (form_element.isNull()) { | |
1133 // No associated form, try the synthetic form for unowned form elements. | |
1134 WebDocument document = element.document(); | |
1135 std::vector<WebElement> fieldsets; | |
1136 std::vector<WebFormControlElement> control_elements = | |
1137 GetUnownedAutofillableFormFieldElements(document.all(), &fieldsets); | |
1138 return UnownedFormElementsAndFieldSetsToFormData( | |
1139 fieldsets, control_elements, &element, document.url(), requirements, | |
1140 extract_mask, form, field); | |
1141 } | |
1142 | |
1049 return WebFormElementToFormData(form_element, | 1143 return WebFormElementToFormData(form_element, |
1050 element, | 1144 element, |
1051 requirements, | 1145 requirements, |
1052 extract_mask, | 1146 extract_mask, |
1053 form, | 1147 form, |
1054 field); | 1148 field); |
1055 } | 1149 } |
1056 | 1150 |
1057 void FillForm(const FormData& form, const WebFormControlElement& element) { | 1151 void FillForm(const FormData& form, const WebFormControlElement& element) { |
1058 WebFormElement form_element = element.form(); | 1152 WebFormElement form_element = element.form(); |
1059 if (form_element.isNull()) | 1153 if (form_element.isNull()) { |
1154 ForEachMatchingUnownedFormField(element, | |
1155 form, | |
1156 FILTER_ALL_NON_EDITABLE_ELEMENTS, | |
1157 false, /* dont force override */ | |
1158 &FillFormField); | |
1060 return; | 1159 return; |
1160 } | |
1061 | 1161 |
1062 ForEachMatchingFormField(form_element, | 1162 ForEachMatchingFormField(form_element, |
1063 element, | 1163 element, |
1064 form, | 1164 form, |
1065 FILTER_ALL_NON_EDITABLE_ELEMENTS, | 1165 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
1066 false, /* dont force override */ | 1166 false, /* dont force override */ |
1067 &FillFormField); | 1167 &FillFormField); |
1068 } | 1168 } |
1069 | 1169 |
1070 void FillFormIncludingNonFocusableElements(const FormData& form_data, | 1170 void FillFormIncludingNonFocusableElements(const FormData& form_data, |
1071 const WebFormElement& form_element) { | 1171 const WebFormElement& form_element) { |
1072 if (form_element.isNull()) | 1172 if (form_element.isNull()) { |
1173 NOTREACHED(); | |
1073 return; | 1174 return; |
1175 } | |
1074 | 1176 |
1075 FieldFilterMask filter_mask = static_cast<FieldFilterMask>( | 1177 FieldFilterMask filter_mask = static_cast<FieldFilterMask>( |
1076 FILTER_DISABLED_ELEMENTS | FILTER_READONLY_ELEMENTS); | 1178 FILTER_DISABLED_ELEMENTS | FILTER_READONLY_ELEMENTS); |
1077 ForEachMatchingFormField(form_element, | 1179 ForEachMatchingFormField(form_element, |
1078 WebInputElement(), | 1180 WebInputElement(), |
1079 form_data, | 1181 form_data, |
1080 filter_mask, | 1182 filter_mask, |
1081 true, /* force override */ | 1183 true, /* force override */ |
1082 &FillFormField); | 1184 &FillFormField); |
1083 } | 1185 } |
1084 | 1186 |
1085 void PreviewForm(const FormData& form, const WebFormControlElement& element) { | 1187 void PreviewForm(const FormData& form, const WebFormControlElement& element) { |
1086 WebFormElement form_element = element.form(); | 1188 WebFormElement form_element = element.form(); |
1087 if (form_element.isNull()) | 1189 if (form_element.isNull()) { |
1190 ForEachMatchingUnownedFormField(element, | |
1191 form, | |
1192 FILTER_ALL_NON_EDITABLE_ELEMENTS, | |
1193 false, /* dont force override */ | |
1194 &PreviewFormField); | |
1088 return; | 1195 return; |
1196 } | |
1089 | 1197 |
1090 ForEachMatchingFormField(form_element, | 1198 ForEachMatchingFormField(form_element, |
1091 element, | 1199 element, |
1092 form, | 1200 form, |
1093 FILTER_ALL_NON_EDITABLE_ELEMENTS, | 1201 FILTER_ALL_NON_EDITABLE_ELEMENTS, |
1094 false, /* dont force override */ | 1202 false, /* dont force override */ |
1095 &PreviewFormField); | 1203 &PreviewFormField); |
1096 } | 1204 } |
1097 | 1205 |
1098 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, | 1206 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, |
1099 bool was_autofilled) { | 1207 bool was_autofilled) { |
1100 WebFormElement form_element = element.form(); | 1208 WebFormElement form_element = element.form(); |
1101 if (form_element.isNull()) | 1209 std::vector<WebFormControlElement> control_elements; |
1102 return false; | 1210 if (form_element.isNull()) { |
1211 control_elements = GetUnownedAutofillableFormFieldElements( | |
1212 element.document().all(), nullptr); | |
1213 if (!IsElementInControlElementSet(element, control_elements)) | |
1214 return false; | |
1215 } else { | |
1216 control_elements = ExtractAutofillableElementsInForm( | |
1217 form_element, ExtractionRequirements()); | |
1218 } | |
1103 | 1219 |
1104 std::vector<WebFormControlElement> control_elements = | |
1105 ExtractAutofillableElementsInForm(form_element, ExtractionRequirements()); | |
1106 for (size_t i = 0; i < control_elements.size(); ++i) { | 1220 for (size_t i = 0; i < control_elements.size(); ++i) { |
1107 // There might be unrelated elements in this form which have already been | 1221 // 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 | 1222 // 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 | 1223 // 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. | 1224 // want to reset the auto-filled status for fields that were previewed. |
1111 WebFormControlElement control_element = control_elements[i]; | 1225 WebFormControlElement control_element = control_elements[i]; |
1112 | 1226 |
1113 // Only text input, textarea and select elements can be previewed. | 1227 // Only text input, textarea and select elements can be previewed. |
1114 WebInputElement* input_element = toWebInputElement(&control_element); | 1228 WebInputElement* input_element = toWebInputElement(&control_element); |
1115 if (!IsTextInput(input_element) && | 1229 if (!IsTextInput(input_element) && |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1208 | 1322 |
1209 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { | 1323 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { |
1210 gfx::Rect bounding_box(element->boundsInViewportSpace()); | 1324 gfx::Rect bounding_box(element->boundsInViewportSpace()); |
1211 return gfx::RectF(bounding_box.x() * scale, | 1325 return gfx::RectF(bounding_box.x() * scale, |
1212 bounding_box.y() * scale, | 1326 bounding_box.y() * scale, |
1213 bounding_box.width() * scale, | 1327 bounding_box.width() * scale, |
1214 bounding_box.height() * scale); | 1328 bounding_box.height() * scale); |
1215 } | 1329 } |
1216 | 1330 |
1217 } // namespace autofill | 1331 } // namespace autofill |
OLD | NEW |