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/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/stl_util.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" |
16 #include "components/autofill/core/common/form_field_data.h" | 17 #include "components/autofill/core/common/form_field_data.h" |
17 #include "components/autofill/core/common/password_autofill_util.h" | 18 #include "components/autofill/core/common/password_autofill_util.h" |
18 #include "components/autofill/core/common/password_form.h" | 19 #include "components/autofill/core/common/password_form.h" |
19 #include "components/autofill/core/common/password_form_fill_data.h" | 20 #include "components/autofill/core/common/password_form_fill_data.h" |
20 #include "content/public/common/page_transition_types.h" | 21 #include "content/public/common/page_transition_types.h" |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 elements_.clear(); | 267 elements_.clear(); |
267 } | 268 } |
268 | 269 |
269 void PasswordAutofillAgent::PasswordValueGatekeeper::Reset() { | 270 void PasswordAutofillAgent::PasswordValueGatekeeper::Reset() { |
270 was_user_gesture_seen_ = false; | 271 was_user_gesture_seen_ = false; |
271 elements_.clear(); | 272 elements_.clear(); |
272 } | 273 } |
273 | 274 |
274 void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue( | 275 void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue( |
275 blink::WebInputElement* element) { | 276 blink::WebInputElement* element) { |
276 if (!element->isNull() && !element->suggestedValue().isNull()) | 277 if (!element->isNull() && element->value().isNull() && |
278 !element->suggestedValue().isNull()) { | |
277 element->setValue(element->suggestedValue(), true); | 279 element->setValue(element->suggestedValue(), true); |
280 element->setSuggestedValue(blink::WebString()); | |
281 } | |
278 } | 282 } |
279 | 283 |
280 bool PasswordAutofillAgent::TextFieldDidEndEditing( | 284 bool PasswordAutofillAgent::TextFieldDidEndEditing( |
281 const blink::WebInputElement& element) { | 285 const blink::WebInputElement& element) { |
282 LoginToPasswordInfoMap::const_iterator iter = | 286 LoginToPasswordInfoMap::const_iterator iter = |
283 login_to_password_info_.find(element); | 287 login_to_password_info_.find(element); |
284 if (iter == login_to_password_info_.end()) | 288 if (iter == login_to_password_info_.end()) |
285 return false; | 289 return false; |
286 | 290 |
287 const PasswordFormFillData& fill_data = iter->second.fill_data; | 291 const PasswordFormFillData& fill_data = iter->second.fill_data; |
(...skipping 13 matching lines...) Expand all Loading... | |
301 FillUserNameAndPassword(&username, | 305 FillUserNameAndPassword(&username, |
302 &password, | 306 &password, |
303 fill_data, | 307 fill_data, |
304 true /* exact_username_match */, | 308 true /* exact_username_match */, |
305 false /* set_selection */); | 309 false /* set_selection */); |
306 return true; | 310 return true; |
307 } | 311 } |
308 | 312 |
309 bool PasswordAutofillAgent::TextDidChangeInTextField( | 313 bool PasswordAutofillAgent::TextDidChangeInTextField( |
310 const blink::WebInputElement& element) { | 314 const blink::WebInputElement& element) { |
315 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 | |
316 blink::WebInputElement mutable_element = element; // We need a non-const. | |
317 | |
318 if (element.isPasswordField()) { | |
319 PasswordToLoginMap::iterator iter = password_to_username_.find(element); | |
320 if (iter != password_to_username_.end()) { | |
321 temporary_disabled_password_fill_.insert(iter->second); | |
322 mutable_element.setAutofilled(false); | |
323 } | |
324 return false; | |
325 } | |
326 | |
311 LoginToPasswordInfoMap::const_iterator iter = | 327 LoginToPasswordInfoMap::const_iterator iter = |
312 login_to_password_info_.find(element); | 328 login_to_password_info_.find(element); |
313 if (iter == login_to_password_info_.end()) | 329 if (iter == login_to_password_info_.end()) |
314 return false; | 330 return false; |
315 | 331 |
316 // The input text is being changed, so any autofilled password is now | 332 // The input text is being changed, so any autofilled password is now |
317 // outdated. | 333 // outdated. |
318 blink::WebInputElement username = element; // We need a non-const. | 334 mutable_element.setAutofilled(false); |
319 username.setAutofilled(false); | 335 temporary_disabled_password_fill_.erase(element); |
320 | 336 |
321 blink::WebInputElement password = iter->second.password_field; | 337 blink::WebInputElement password = iter->second.password_field; |
322 if (password.isAutofilled()) { | 338 if (password.isAutofilled()) { |
323 password.setValue(base::string16(), true); | 339 password.setValue(base::string16(), true); |
324 password.setAutofilled(false); | 340 password.setAutofilled(false); |
325 } | 341 } |
326 | 342 |
327 // If wait_for_username is true we will fill when the username loses focus. | 343 // If wait_for_username is true we will fill when the username loses focus. |
328 if (iter->second.fill_data.wait_for_username) | 344 if (iter->second.fill_data.wait_for_username) |
329 return false; | 345 return false; |
330 | 346 |
331 if (!element.isText() || !IsElementAutocompletable(element) || | 347 if (!element.isText() || !IsElementAutocompletable(element) || |
332 !IsElementAutocompletable(password)) { | 348 !IsElementAutocompletable(password)) { |
333 return false; | 349 return false; |
334 } | 350 } |
335 | 351 |
336 // Don't inline autocomplete if the user is deleting, that would be confusing. | 352 // Don't inline autocomplete if the user is deleting, that would be confusing. |
337 // But refresh the popup. Note, since this is ours, return true to signal | 353 // But refresh the popup. Note, since this is ours, return true to signal |
338 // no further processing is required. | 354 // no further processing is required. |
339 if (iter->second.backspace_pressed_last) { | 355 if (iter->second.backspace_pressed_last) { |
340 ShowSuggestionPopup(iter->second.fill_data, username, false); | 356 ShowSuggestionPopup(iter->second.fill_data, element, false); |
341 return true; | 357 return true; |
342 } | 358 } |
343 | 359 |
344 blink::WebString name = element.nameForAutofill(); | 360 blink::WebString name = element.nameForAutofill(); |
345 if (name.isEmpty()) | 361 if (name.isEmpty()) |
346 return false; // If the field has no name, then we won't have values. | 362 return false; // If the field has no name, then we won't have values. |
347 | 363 |
348 // Don't attempt to autofill with values that are too large. | 364 // Don't attempt to autofill with values that are too large. |
349 if (element.value().length() > kMaximumTextSizeForAutocomplete) | 365 if (element.value().length() > kMaximumTextSizeForAutocomplete) |
350 return false; | 366 return false; |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
783 // We might have already filled this form if there are two <form> elements | 799 // We might have already filled this form if there are two <form> elements |
784 // with identical markup. | 800 // with identical markup. |
785 if (login_to_password_info_.find(username_element) != | 801 if (login_to_password_info_.find(username_element) != |
786 login_to_password_info_.end()) | 802 login_to_password_info_.end()) |
787 continue; | 803 continue; |
788 | 804 |
789 PasswordInfo password_info; | 805 PasswordInfo password_info; |
790 password_info.fill_data = form_data; | 806 password_info.fill_data = form_data; |
791 password_info.password_field = password_element; | 807 password_info.password_field = password_element; |
792 login_to_password_info_[username_element] = password_info; | 808 login_to_password_info_[username_element] = password_info; |
809 password_to_username_[password_element] = username_element; | |
793 | 810 |
794 FormData form; | 811 FormData form; |
795 FormFieldData field; | 812 FormFieldData field; |
796 FindFormAndFieldForFormControlElement( | 813 FindFormAndFieldForFormControlElement( |
797 username_element, &form, &field, REQUIRE_NONE); | 814 username_element, &form, &field, REQUIRE_NONE); |
798 Send(new AutofillHostMsg_AddPasswordFormMapping( | 815 Send(new AutofillHostMsg_AddPasswordFormMapping( |
799 routing_id(), field, form_data)); | 816 routing_id(), field, form_data)); |
800 } | 817 } |
801 } | 818 } |
802 | 819 |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
912 true /* exact_username_match */, | 929 true /* exact_username_match */, |
913 false /* set_selection */); | 930 false /* set_selection */); |
914 } | 931 } |
915 | 932 |
916 bool PasswordAutofillAgent::FillUserNameAndPassword( | 933 bool PasswordAutofillAgent::FillUserNameAndPassword( |
917 blink::WebInputElement* username_element, | 934 blink::WebInputElement* username_element, |
918 blink::WebInputElement* password_element, | 935 blink::WebInputElement* password_element, |
919 const PasswordFormFillData& fill_data, | 936 const PasswordFormFillData& fill_data, |
920 bool exact_username_match, | 937 bool exact_username_match, |
921 bool set_selection) { | 938 bool set_selection) { |
939 if (ContainsKey(temporary_disabled_password_fill_, *username_element)) | |
engedy
2014/07/29 14:43:54
As discussed offline, many of these helper functio
vabr (Chromium)
2014/07/29 15:12:30
Done: the knowledge of this particular bit removed
| |
940 return false; | |
922 base::string16 current_username = username_element->value(); | 941 base::string16 current_username = username_element->value(); |
923 // username and password will contain the match found if any. | 942 // username and password will contain the match found if any. |
924 base::string16 username; | 943 base::string16 username; |
925 base::string16 password; | 944 base::string16 password; |
926 | 945 |
927 // Look for any suitable matches to current field text. | 946 // Look for any suitable matches to current field text. |
928 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, | 947 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, |
929 current_username, | 948 current_username, |
930 exact_username_match)) { | 949 exact_username_match)) { |
931 username = fill_data.basic_data.fields[0].value; | 950 username = fill_data.basic_data.fields[0].value; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1027 &password, | 1046 &password, |
1028 fill_data, | 1047 fill_data, |
1029 false /* exact_username_match */, | 1048 false /* exact_username_match */, |
1030 true /* set_selection */); | 1049 true /* set_selection */); |
1031 #endif | 1050 #endif |
1032 } | 1051 } |
1033 | 1052 |
1034 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { | 1053 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { |
1035 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); | 1054 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
1036 iter != login_to_password_info_.end();) { | 1055 iter != login_to_password_info_.end();) { |
1037 if (iter->first.document().frame() == frame) | 1056 if (iter->first.document().frame() == frame) { |
1057 password_to_username_.erase(iter->second.password_field); | |
1058 temporary_disabled_password_fill_.erase(iter->first); | |
1038 login_to_password_info_.erase(iter++); | 1059 login_to_password_info_.erase(iter++); |
1039 else | 1060 } else { |
1040 ++iter; | 1061 ++iter; |
1062 } | |
1041 } | 1063 } |
1042 for (FrameToPasswordFormMap::iterator iter = | 1064 for (FrameToPasswordFormMap::iterator iter = |
1043 provisionally_saved_forms_.begin(); | 1065 provisionally_saved_forms_.begin(); |
1044 iter != provisionally_saved_forms_.end();) { | 1066 iter != provisionally_saved_forms_.end();) { |
1045 if (iter->first == frame) | 1067 if (iter->first == frame) |
1046 provisionally_saved_forms_.erase(iter++); | 1068 provisionally_saved_forms_.erase(iter++); |
1047 else | 1069 else |
1048 ++iter; | 1070 ++iter; |
1049 } | 1071 } |
1050 } | 1072 } |
(...skipping 27 matching lines...) Expand all Loading... | |
1078 username->setSelectionRange(username_selection_start_, | 1100 username->setSelectionRange(username_selection_start_, |
1079 username->value().length()); | 1101 username->value().length()); |
1080 } | 1102 } |
1081 if (!password->suggestedValue().isEmpty()) { | 1103 if (!password->suggestedValue().isEmpty()) { |
1082 password->setSuggestedValue(blink::WebString()); | 1104 password->setSuggestedValue(blink::WebString()); |
1083 password->setAutofilled(was_password_autofilled_); | 1105 password->setAutofilled(was_password_autofilled_); |
1084 } | 1106 } |
1085 } | 1107 } |
1086 | 1108 |
1087 } // namespace autofill | 1109 } // namespace autofill |
OLD | NEW |