Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1291)

Side by Side Diff: components/autofill/content/renderer/password_autofill_agent.cc

Issue 414013003: Password autofill should not override explicitly typed password (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Don't give up autocompletion completely Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698