| 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 |