| 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" |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 47 using blink::WebNodeList; | 47 using blink::WebNodeList; |
| 48 using blink::WebOptionElement; | 48 using blink::WebOptionElement; |
| 49 using blink::WebSelectElement; | 49 using blink::WebSelectElement; |
| 50 using blink::WebTextAreaElement; | 50 using blink::WebTextAreaElement; |
| 51 using blink::WebString; | 51 using blink::WebString; |
| 52 using blink::WebVector; | 52 using blink::WebVector; |
| 53 | 53 |
| 54 namespace autofill { | 54 namespace autofill { |
| 55 namespace { | 55 namespace { |
| 56 | 56 |
| 57 // A bit field mask for FillForm functions to not fill some fields. |
| 58 enum FieldFilterMask { |
| 59 FILTER_NONE = 0, |
| 60 FILTER_DISABLED_ELEMENTS = 1 << 0, |
| 61 FILTER_READONLY_ELEMENTS = 1 << 1, |
| 62 FILTER_NON_FOCUSABLE_ELEMENTS = 1 << 2, |
| 63 FILTER_ALL_NON_EDITIABLE_ELEMENTS = FILTER_DISABLED_ELEMENTS | |
| 64 FILTER_READONLY_ELEMENTS | |
| 65 FILTER_NON_FOCUSABLE_ELEMENTS, |
| 66 }; |
| 67 |
| 57 bool IsOptionElement(const WebElement& element) { | 68 bool IsOptionElement(const WebElement& element) { |
| 58 CR_DEFINE_STATIC_LOCAL(WebString, kOption, ("option")); | 69 CR_DEFINE_STATIC_LOCAL(WebString, kOption, ("option")); |
| 59 return element.hasHTMLTagName(kOption); | 70 return element.hasHTMLTagName(kOption); |
| 60 } | 71 } |
| 61 | 72 |
| 62 bool IsScriptElement(const WebElement& element) { | 73 bool IsScriptElement(const WebElement& element) { |
| 63 CR_DEFINE_STATIC_LOCAL(WebString, kScript, ("script")); | 74 CR_DEFINE_STATIC_LOCAL(WebString, kScript, ("script")); |
| 64 return element.hasHTMLTagName(kScript); | 75 return element.hasHTMLTagName(kScript); |
| 65 } | 76 } |
| 66 | 77 |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 458 // The callback type used by |ForEachMatchingFormField()|. | 469 // The callback type used by |ForEachMatchingFormField()|. |
| 459 typedef void (*Callback)(const FormFieldData&, | 470 typedef void (*Callback)(const FormFieldData&, |
| 460 bool, /* is_initiating_element */ | 471 bool, /* is_initiating_element */ |
| 461 blink::WebFormControlElement*); | 472 blink::WebFormControlElement*); |
| 462 | 473 |
| 463 // For each autofillable field in |data| that matches a field in the |form|, | 474 // For each autofillable field in |data| that matches a field in the |form|, |
| 464 // the |callback| is invoked with the corresponding |form| field data. | 475 // the |callback| is invoked with the corresponding |form| field data. |
| 465 void ForEachMatchingFormField(const WebFormElement& form_element, | 476 void ForEachMatchingFormField(const WebFormElement& form_element, |
| 466 const WebElement& initiating_element, | 477 const WebElement& initiating_element, |
| 467 const FormData& data, | 478 const FormData& data, |
| 468 bool only_focusable_elements, | 479 FieldFilterMask filters, |
| 469 bool force_override, | 480 bool force_override, |
| 470 Callback callback) { | 481 Callback callback) { |
| 471 std::vector<WebFormControlElement> control_elements; | 482 std::vector<WebFormControlElement> control_elements; |
| 472 ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE, | 483 ExtractAutofillableElements(form_element, REQUIRE_AUTOCOMPLETE, |
| 473 &control_elements); | 484 &control_elements); |
| 474 | 485 |
| 475 if (control_elements.size() != data.fields.size()) { | 486 if (control_elements.size() != data.fields.size()) { |
| 476 // This case should be reachable only for pathological websites and tests, | 487 // This case should be reachable only for pathological websites and tests, |
| 477 // which add or remove form fields while the user is interacting with the | 488 // which add or remove form fields while the user is interacting with the |
| 478 // Autofill popup. | 489 // Autofill popup. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 501 | 512 |
| 502 // Only autofill empty fields and the field that initiated the filling, | 513 // Only autofill empty fields and the field that initiated the filling, |
| 503 // i.e. the field the user is currently editing and interacting with. | 514 // i.e. the field the user is currently editing and interacting with. |
| 504 const WebInputElement* input_element = toWebInputElement(element); | 515 const WebInputElement* input_element = toWebInputElement(element); |
| 505 if (!force_override && !is_initiating_element && | 516 if (!force_override && !is_initiating_element && |
| 506 ((IsAutofillableInputElement(input_element) || | 517 ((IsAutofillableInputElement(input_element) || |
| 507 IsTextAreaElement(*element)) && | 518 IsTextAreaElement(*element)) && |
| 508 !element->value().isEmpty())) | 519 !element->value().isEmpty())) |
| 509 continue; | 520 continue; |
| 510 | 521 |
| 511 if (!element->isEnabled() || element->isReadOnly() || | 522 if (((filters & FILTER_DISABLED_ELEMENTS) && !element->isEnabled()) || |
| 512 (only_focusable_elements && !element->isFocusable())) | 523 ((filters & FILTER_READONLY_ELEMENTS) && element->isReadOnly()) || |
| 524 ((filters & FILTER_NON_FOCUSABLE_ELEMENTS) && !element->isFocusable())) |
| 513 continue; | 525 continue; |
| 514 | 526 |
| 515 callback(data.fields[i], is_initiating_element, element); | 527 callback(data.fields[i], is_initiating_element, element); |
| 516 } | 528 } |
| 517 } | 529 } |
| 518 | 530 |
| 519 // Sets the |field|'s value to the value in |data|. | 531 // Sets the |field|'s value to the value in |data|. |
| 520 // Also sets the "autofilled" attribute, causing the background to be yellow. | 532 // Also sets the "autofilled" attribute, causing the background to be yellow. |
| 521 void FillFormField(const FormFieldData& data, | 533 void FillFormField(const FormFieldData& data, |
| 522 bool is_initiating_node, | 534 bool is_initiating_node, |
| (...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } | 994 } |
| 983 | 995 |
| 984 void FillForm(const FormData& form, const WebFormControlElement& element) { | 996 void FillForm(const FormData& form, const WebFormControlElement& element) { |
| 985 WebFormElement form_element = element.form(); | 997 WebFormElement form_element = element.form(); |
| 986 if (form_element.isNull()) | 998 if (form_element.isNull()) |
| 987 return; | 999 return; |
| 988 | 1000 |
| 989 ForEachMatchingFormField(form_element, | 1001 ForEachMatchingFormField(form_element, |
| 990 element, | 1002 element, |
| 991 form, | 1003 form, |
| 992 true, /* only_focusable_elements */ | 1004 FILTER_ALL_NON_EDITIABLE_ELEMENTS, |
| 993 false, /* don't force override */ | 1005 false, /* dont force override */ |
| 994 &FillFormField); | 1006 &FillFormField); |
| 995 } | 1007 } |
| 996 | 1008 |
| 997 void FillFormIncludingNonFocusableElements(const FormData& form_data, | 1009 void FillFormIncludingNonFocusableElements(const FormData& form_data, |
| 998 const WebFormElement& form_element) { | 1010 const WebFormElement& form_element) { |
| 999 if (form_element.isNull()) | 1011 if (form_element.isNull()) |
| 1000 return; | 1012 return; |
| 1001 | 1013 |
| 1014 FieldFilterMask filter_mask = static_cast<FieldFilterMask>( |
| 1015 FILTER_DISABLED_ELEMENTS | FILTER_READONLY_ELEMENTS); |
| 1016 ForEachMatchingFormField(form_element, |
| 1017 WebInputElement(), |
| 1018 form_data, |
| 1019 filter_mask, |
| 1020 true, /* force override */ |
| 1021 &FillFormField); |
| 1022 } |
| 1023 |
| 1024 void FillFormForAllElements(const FormData& form_data, |
| 1025 const WebFormElement& form_element) { |
| 1026 if (form_element.isNull()) |
| 1027 return; |
| 1028 |
| 1002 ForEachMatchingFormField(form_element, | 1029 ForEachMatchingFormField(form_element, |
| 1003 WebInputElement(), | 1030 WebInputElement(), |
| 1004 form_data, | 1031 form_data, |
| 1005 false, /* only_focusable_elements */ | 1032 FILTER_NONE, |
| 1006 true, /* force override */ | 1033 true, /* force override */ |
| 1007 &FillFormField); | 1034 &FillFormField); |
| 1008 } | 1035 } |
| 1009 | 1036 |
| 1010 void PreviewForm(const FormData& form, const WebFormControlElement& element) { | 1037 void PreviewForm(const FormData& form, const WebFormControlElement& element) { |
| 1011 WebFormElement form_element = element.form(); | 1038 WebFormElement form_element = element.form(); |
| 1012 if (form_element.isNull()) | 1039 if (form_element.isNull()) |
| 1013 return; | 1040 return; |
| 1014 | 1041 |
| 1015 ForEachMatchingFormField(form_element, | 1042 ForEachMatchingFormField(form_element, |
| 1016 element, | 1043 element, |
| 1017 form, | 1044 form, |
| 1018 true, /* only_focusable_elements */ | 1045 FILTER_ALL_NON_EDITIABLE_ELEMENTS, |
| 1019 false, /* dont force override */ | 1046 false, /* dont force override */ |
| 1020 &PreviewFormField); | 1047 &PreviewFormField); |
| 1021 } | 1048 } |
| 1022 | 1049 |
| 1023 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, | 1050 bool ClearPreviewedFormWithElement(const WebFormControlElement& element, |
| 1024 bool was_autofilled) { | 1051 bool was_autofilled) { |
| 1025 WebFormElement form_element = element.form(); | 1052 WebFormElement form_element = element.form(); |
| 1026 if (form_element.isNull()) | 1053 if (form_element.isNull()) |
| 1027 return false; | 1054 return false; |
| 1028 | 1055 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 | 1181 |
| 1155 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { | 1182 gfx::RectF GetScaledBoundingBox(float scale, WebFormControlElement* element) { |
| 1156 gfx::Rect bounding_box(element->boundsInViewportSpace()); | 1183 gfx::Rect bounding_box(element->boundsInViewportSpace()); |
| 1157 return gfx::RectF(bounding_box.x() * scale, | 1184 return gfx::RectF(bounding_box.x() * scale, |
| 1158 bounding_box.y() * scale, | 1185 bounding_box.y() * scale, |
| 1159 bounding_box.width() * scale, | 1186 bounding_box.width() * scale, |
| 1160 bounding_box.height() * scale); | 1187 bounding_box.height() * scale); |
| 1161 } | 1188 } |
| 1162 | 1189 |
| 1163 } // namespace autofill | 1190 } // namespace autofill |
| OLD | NEW |