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/password_autofill_agent.h" | 5 #include "components/autofill/content/renderer/password_autofill_agent.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | |
8 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
10 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
11 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
12 #include "components/autofill/content/common/autofill_messages.h" | 13 #include "components/autofill/content/common/autofill_messages.h" |
13 #include "components/autofill/content/renderer/form_autofill_util.h" | 14 #include "components/autofill/content/renderer/form_autofill_util.h" |
14 #include "components/autofill/content/renderer/password_form_conversion_utils.h" | 15 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
15 #include "components/autofill/content/renderer/renderer_save_password_progress_l ogger.h" | 16 #include "components/autofill/content/renderer/renderer_save_password_progress_l ogger.h" |
17 #include "components/autofill/core/common/autofill_switches.h" | |
16 #include "components/autofill/core/common/form_field_data.h" | 18 #include "components/autofill/core/common/form_field_data.h" |
17 #include "components/autofill/core/common/password_autofill_util.h" | 19 #include "components/autofill/core/common/password_autofill_util.h" |
18 #include "components/autofill/core/common/password_form.h" | 20 #include "components/autofill/core/common/password_form.h" |
19 #include "components/autofill/core/common/password_form_fill_data.h" | 21 #include "components/autofill/core/common/password_form_fill_data.h" |
20 #include "content/public/common/page_transition_types.h" | 22 #include "content/public/common/page_transition_types.h" |
21 #include "content/public/renderer/document_state.h" | 23 #include "content/public/renderer/document_state.h" |
22 #include "content/public/renderer/navigation_state.h" | 24 #include "content/public/renderer/navigation_state.h" |
23 #include "content/public/renderer/render_view.h" | 25 #include "content/public/renderer/render_view.h" |
24 #include "third_party/WebKit/public/platform/WebVector.h" | 26 #include "third_party/WebKit/public/platform/WebVector.h" |
25 #include "third_party/WebKit/public/web/WebAutofillClient.h" | 27 #include "third_party/WebKit/public/web/WebAutofillClient.h" |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
294 if (!IsElementEditable(password)) | 296 if (!IsElementEditable(password)) |
295 return false; | 297 return false; |
296 | 298 |
297 blink::WebInputElement username = element; // We need a non-const. | 299 blink::WebInputElement username = element; // We need a non-const. |
298 | 300 |
299 // Do not set selection when ending an editing session, otherwise it can | 301 // Do not set selection when ending an editing session, otherwise it can |
300 // mess with focus. | 302 // mess with focus. |
301 FillUserNameAndPassword(&username, | 303 FillUserNameAndPassword(&username, |
302 &password, | 304 &password, |
303 fill_data, | 305 fill_data, |
304 true /* exact_username_match */, | 306 EXACT_USERNAME_MATCH); |
305 false /* set_selection */); | |
306 return true; | 307 return true; |
307 } | 308 } |
308 | 309 |
309 bool PasswordAutofillAgent::TextDidChangeInTextField( | 310 bool PasswordAutofillAgent::TextDidChangeInTextField( |
310 const blink::WebInputElement& element) { | 311 const blink::WebInputElement& element) { |
311 if (element.isPasswordField()) { | 312 if (element.isPasswordField()) { |
312 // Some login forms have event handlers that put a hash of the password into | 313 // Some login forms have event handlers that put a hash of the password into |
313 // a hidden field and then clear the password (http://crbug.com/28910, | 314 // a hidden field and then clear the password (http://crbug.com/28910, |
314 // http://crbug.com/391693). This method gets called before any of those | 315 // http://crbug.com/391693). This method gets called before any of those |
315 // handlers run, so save away a copy of the password in case it gets lost. | 316 // handlers run, so save away a copy of the password in case it gets lost. |
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
910 return; | 911 return; |
911 | 912 |
912 if (!ShouldIgnoreAutocompleteOffForPasswordFields() && | 913 if (!ShouldIgnoreAutocompleteOffForPasswordFields() && |
913 !username_element.form().autoComplete()) | 914 !username_element.form().autoComplete()) |
914 return; | 915 return; |
915 | 916 |
916 // If we can't modify the password, don't try to set the username | 917 // If we can't modify the password, don't try to set the username |
917 if (!IsElementAutocompletable(password_element)) | 918 if (!IsElementAutocompletable(password_element)) |
918 return; | 919 return; |
919 | 920 |
920 // Try to set the username to the preferred name, but only if the field | |
921 // can be set and isn't prefilled. | |
922 if (IsElementAutocompletable(username_element) && | |
923 username_element.value().isEmpty()) { | |
924 // TODO(tkent): Check maxlength and pattern. | |
925 username_element.setValue(fill_data.basic_data.fields[0].value, true); | |
926 } | |
927 | |
928 // Fill if we have an exact match for the username. Note that this sets | 921 // Fill if we have an exact match for the username. Note that this sets |
929 // username to autofilled. | 922 // username to autofilled. |
930 FillUserNameAndPassword(&username_element, | 923 FillUserNameAndPassword(&username_element, |
931 &password_element, | 924 &password_element, |
932 fill_data, | 925 fill_data, |
933 true /* exact_username_match */, | 926 EXACT_USERNAME_MATCH | FILL_PREFERRED_USERNAME); |
934 false /* set_selection */); | |
935 } | 927 } |
936 | 928 |
937 bool PasswordAutofillAgent::FillUserNameAndPassword( | 929 bool PasswordAutofillAgent::FillUserNameAndPassword( |
938 blink::WebInputElement* username_element, | 930 blink::WebInputElement* username_element, |
939 blink::WebInputElement* password_element, | 931 blink::WebInputElement* password_element, |
940 const PasswordFormFillData& fill_data, | 932 const PasswordFormFillData& fill_data, |
941 bool exact_username_match, | 933 const int options) { |
Garrett Casto
2014/09/08 21:27:20
So I think that the behavior if the username if al
jww
2014/09/09 01:40:34
I was admittedly a bit confused by your comment, b
| |
942 bool set_selection) { | 934 bool exact_username_match = (options & EXACT_USERNAME_MATCH) != 0; |
935 bool set_selection = (options & SET_SELECTION) != 0; | |
936 bool fill_preferred_username = (options & FILL_PREFERRED_USERNAME) != 0; | |
937 bool fill_on_account_select = CommandLine::ForCurrentProcess()->HasSwitch( | |
938 switches::kEnableFillOnAccountSelect); | |
Garrett Casto
2014/09/08 21:27:20
You should pull this out into a function so that w
jww
2014/09/09 01:40:34
Done.
| |
943 base::string16 current_username = username_element->value(); | 939 base::string16 current_username = username_element->value(); |
944 // username and password will contain the match found if any. | 940 // username and password will contain the match found if any. |
945 base::string16 username; | 941 base::string16 username; |
946 base::string16 password; | 942 base::string16 password; |
947 | 943 |
944 // Try to set the username to the preferred name, but only if the field | |
945 // can be set and isn't prefilled. If FILL_PREFERRED_USERNAME | |
946 // is set, set |current_username| to the preferred value, but don't set the | |
947 // element's value. This is done so that even if values aren't actually | |
948 // filled, if there is a valid value to fill with, the elements will be | |
949 // properly marked as autofilled later. | |
950 if (fill_preferred_username && | |
951 IsElementAutocompletable(*username_element) && | |
952 username_element->value().isEmpty()) { | |
953 current_username = fill_data.basic_data.fields[0].value; | |
954 if (!fill_on_account_select) { | |
955 // TODO(tkent): Check maxlength and pattern. | |
956 username_element->setValue(current_username, true); | |
957 } | |
958 } | |
959 | |
948 // Look for any suitable matches to current field text. | 960 // Look for any suitable matches to current field text. |
949 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, | 961 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, |
950 current_username, | 962 current_username, |
951 exact_username_match)) { | 963 exact_username_match)) { |
952 username = fill_data.basic_data.fields[0].value; | 964 username = fill_data.basic_data.fields[0].value; |
953 password = fill_data.basic_data.fields[1].value; | 965 password = fill_data.basic_data.fields[1].value; |
954 } else { | 966 } else { |
955 // Scan additional logins for a match. | 967 // Scan additional logins for a match. |
956 PasswordFormFillData::LoginCollection::const_iterator iter; | 968 PasswordFormFillData::LoginCollection::const_iterator iter; |
957 for (iter = fill_data.additional_logins.begin(); | 969 for (iter = fill_data.additional_logins.begin(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
991 // TODO(tkent): Check maxlength and pattern for both username and password | 1003 // TODO(tkent): Check maxlength and pattern for both username and password |
992 // fields. | 1004 // fields. |
993 | 1005 |
994 // Don't fill username if password can't be set. | 1006 // Don't fill username if password can't be set. |
995 if (!IsElementAutocompletable(*password_element)) { | 1007 if (!IsElementAutocompletable(*password_element)) { |
996 return false; | 1008 return false; |
997 } | 1009 } |
998 | 1010 |
999 // Input matches the username, fill in required values. | 1011 // Input matches the username, fill in required values. |
1000 if (IsElementAutocompletable(*username_element)) { | 1012 if (IsElementAutocompletable(*username_element)) { |
1001 username_element->setValue(username, true); | |
1002 username_element->setAutofilled(true); | 1013 username_element->setAutofilled(true); |
1003 | 1014 |
1004 if (set_selection) { | 1015 if (!fill_on_account_select) { |
1005 username_element->setSelectionRange(current_username.length(), | 1016 username_element->setValue(username, true); |
1006 username.length()); | 1017 |
1018 if (set_selection) { | |
1019 username_element->setSelectionRange(current_username.length(), | |
1020 username.length()); | |
1021 } | |
1007 } | 1022 } |
1008 } else if (current_username != username) { | 1023 } else if (current_username != username) { |
1009 // If the username can't be filled and it doesn't match a saved password | 1024 // If the username can't be filled and it doesn't match a saved password |
1010 // as is, don't autofill a password. | 1025 // as is, don't autofill a password. |
1011 return false; | 1026 return false; |
1012 } | 1027 } |
1013 | 1028 |
1014 // Wait to fill in the password until a user gesture occurs. This is to make | 1029 // Wait to fill in the password until a user gesture occurs. This is to make |
1015 // sure that we do not fill in the DOM with a password until we believe the | 1030 // sure that we do not fill in the DOM with a password until we believe the |
1016 // user is intentionally interacting with the page. | 1031 // user is intentionally interacting with the page. |
1017 password_element->setSuggestedValue(password); | 1032 if (!fill_on_account_select) { |
1033 password_element->setSuggestedValue(password); | |
1034 } | |
1018 gatekeeper_.RegisterElement(password_element); | 1035 gatekeeper_.RegisterElement(password_element); |
1019 | 1036 |
1020 password_element->setAutofilled(true); | 1037 password_element->setAutofilled(true); |
1021 return true; | 1038 return true; |
1022 } | 1039 } |
1023 | 1040 |
1024 void PasswordAutofillAgent::PerformInlineAutocomplete( | 1041 void PasswordAutofillAgent::PerformInlineAutocomplete( |
1025 const blink::WebInputElement& username_input, | 1042 const blink::WebInputElement& username_input, |
1026 const blink::WebInputElement& password_input, | 1043 const blink::WebInputElement& password_input, |
1027 const PasswordFormFillData& fill_data) { | 1044 const PasswordFormFillData& fill_data) { |
(...skipping 12 matching lines...) Expand all Loading... | |
1040 | 1057 |
1041 // Show the popup with the list of available usernames. | 1058 // Show the popup with the list of available usernames. |
1042 ShowSuggestionPopup(fill_data, username, false); | 1059 ShowSuggestionPopup(fill_data, username, false); |
1043 | 1060 |
1044 #if !defined(OS_ANDROID) | 1061 #if !defined(OS_ANDROID) |
1045 // Fill the user and password field with the most relevant match. Android | 1062 // Fill the user and password field with the most relevant match. Android |
1046 // only fills in the fields after the user clicks on the suggestion popup. | 1063 // only fills in the fields after the user clicks on the suggestion popup. |
1047 FillUserNameAndPassword(&username, | 1064 FillUserNameAndPassword(&username, |
1048 &password, | 1065 &password, |
1049 fill_data, | 1066 fill_data, |
1050 false /* exact_username_match */, | 1067 SET_SELECTION); |
1051 true /* set_selection */); | |
1052 #endif | 1068 #endif |
1053 } | 1069 } |
1054 | 1070 |
1055 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { | 1071 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { |
1056 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); | 1072 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
1057 iter != login_to_password_info_.end();) { | 1073 iter != login_to_password_info_.end();) { |
1058 if (iter->first.document().frame() == frame) | 1074 if (iter->first.document().frame() == frame) |
1059 login_to_password_info_.erase(iter++); | 1075 login_to_password_info_.erase(iter++); |
1060 else | 1076 else |
1061 ++iter; | 1077 ++iter; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1113 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form)); | 1129 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form)); |
1114 if (!password_form || (restriction == RESTRICTION_NON_EMPTY_PASSWORD && | 1130 if (!password_form || (restriction == RESTRICTION_NON_EMPTY_PASSWORD && |
1115 password_form->password_value.empty() && | 1131 password_form->password_value.empty() && |
1116 password_form->new_password_value.empty())) { | 1132 password_form->new_password_value.empty())) { |
1117 return; | 1133 return; |
1118 } | 1134 } |
1119 provisionally_saved_forms_[frame].reset(password_form.release()); | 1135 provisionally_saved_forms_[frame].reset(password_form.release()); |
1120 } | 1136 } |
1121 | 1137 |
1122 } // namespace autofill | 1138 } // namespace autofill |
OLD | NEW |