Chromium Code Reviews| 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" |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 266 elements_.clear(); | 266 elements_.clear(); |
| 267 } | 267 } |
| 268 | 268 |
| 269 void PasswordAutofillAgent::PasswordValueGatekeeper::Reset() { | 269 void PasswordAutofillAgent::PasswordValueGatekeeper::Reset() { |
| 270 was_user_gesture_seen_ = false; | 270 was_user_gesture_seen_ = false; |
| 271 elements_.clear(); | 271 elements_.clear(); |
| 272 } | 272 } |
| 273 | 273 |
| 274 void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue( | 274 void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue( |
| 275 blink::WebInputElement* element) { | 275 blink::WebInputElement* element) { |
| 276 if (!element->isNull() && !element->suggestedValue().isNull()) | 276 if (!element->isNull() && !element->suggestedValue().isEmpty()) |
| 277 element->setValue(element->suggestedValue(), true); | 277 element->setValue(element->suggestedValue(), true); |
| 278 } | 278 } |
| 279 | 279 |
| 280 bool PasswordAutofillAgent::TextFieldDidEndEditing( | 280 bool PasswordAutofillAgent::TextFieldDidEndEditing( |
| 281 const blink::WebInputElement& element) { | 281 const blink::WebInputElement& element) { |
| 282 LoginToPasswordInfoMap::const_iterator iter = | 282 LoginToPasswordInfoMap::const_iterator iter = |
| 283 login_to_password_info_.find(element); | 283 login_to_password_info_.find(element); |
| 284 if (iter == login_to_password_info_.end()) | 284 if (iter == login_to_password_info_.end()) |
| 285 return false; | 285 return false; |
| 286 | 286 |
| 287 const PasswordFormFillData& fill_data = iter->second.fill_data; | 287 const PasswordInfo& password_info = iter->second; |
| 288 // Don't let autofill overwrite an explicit change made by the user. | |
| 289 if (password_info.wait_for_username_change) | |
| 290 return false; | |
| 291 | |
| 292 const PasswordFormFillData& fill_data = password_info.fill_data; | |
| 288 | 293 |
| 289 // If wait_for_username is false, we should have filled when the text changed. | 294 // If wait_for_username is false, we should have filled when the text changed. |
| 290 if (!fill_data.wait_for_username) | 295 if (!fill_data.wait_for_username) |
| 291 return false; | 296 return false; |
| 292 | 297 |
| 293 blink::WebInputElement password = iter->second.password_field; | 298 blink::WebInputElement password = password_info.password_field; |
| 294 if (!IsElementEditable(password)) | 299 if (!IsElementEditable(password)) |
| 295 return false; | 300 return false; |
| 296 | 301 |
| 297 blink::WebInputElement username = element; // We need a non-const. | 302 blink::WebInputElement username = element; // We need a non-const. |
| 298 | 303 |
| 299 // Do not set selection when ending an editing session, otherwise it can | 304 // Do not set selection when ending an editing session, otherwise it can |
| 300 // mess with focus. | 305 // mess with focus. |
| 301 FillUserNameAndPassword(&username, | 306 FillUserNameAndPassword(&username, |
| 302 &password, | 307 &password, |
| 303 fill_data, | 308 fill_data, |
| 304 true /* exact_username_match */, | 309 true /* exact_username_match */, |
| 305 false /* set_selection */); | 310 false /* set_selection */); |
| 306 return true; | 311 return true; |
| 307 } | 312 } |
| 308 | 313 |
| 309 bool PasswordAutofillAgent::TextDidChangeInTextField( | 314 bool PasswordAutofillAgent::TextDidChangeInTextField( |
| 310 const blink::WebInputElement& element) { | 315 const blink::WebInputElement& element) { |
| 316 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 | |
| 317 blink::WebInputElement mutable_element = element; // We need a non-const. | |
| 318 | |
| 311 if (element.isPasswordField()) { | 319 if (element.isPasswordField()) { |
| 312 // Some login forms have event handlers that put a hash of the password into | 320 // 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, | 321 // 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 | 322 // 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. | 323 // handlers run, so save away a copy of the password in case it gets lost. |
| 316 // To honor the user having explicitly cleared the password, even an empty | 324 // To honor the user having explicitly cleared the password, even an empty |
| 317 // password will be saved here. | 325 // password will be saved here. |
| 318 ProvisionallySavePassword( | 326 ProvisionallySavePassword( |
| 319 element.document().frame(), element.form(), RESTRICTION_NONE); | 327 element.document().frame(), element.form(), RESTRICTION_NONE); |
| 328 | |
| 329 PasswordToLoginMap::iterator iter = password_to_username_.find(element); | |
| 330 if (iter != password_to_username_.end()) { | |
| 331 // The user changed the password after it was autofilled. Flipping the | |
|
engedy
2014/08/06 10:18:17
nit: I would personally drop this comment, and int
vabr (Chromium)
2014/08/25 14:53:29
Comment dropped. The summary came out as a duplica
| |
| 332 // flag below to true makes sure it is not overwritten by autofill | |
| 333 // re-firing for the same username. | |
| 334 login_to_password_info_[iter->second].wait_for_username_change = true; | |
|
engedy
2014/08/06 10:18:17
I think this is not really needed, but for clarity
vabr (Chromium)
2014/08/25 14:53:29
Only made a comment to that effect. The suggested
| |
| 335 mutable_element.setAutofilled(false); | |
| 336 } | |
| 320 return false; | 337 return false; |
| 321 } | 338 } |
| 322 | 339 |
| 323 LoginToPasswordInfoMap::const_iterator iter = | 340 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element); |
| 324 login_to_password_info_.find(element); | |
| 325 if (iter == login_to_password_info_.end()) | 341 if (iter == login_to_password_info_.end()) |
| 326 return false; | 342 return false; |
| 327 | 343 |
| 328 // The input text is being changed, so any autofilled password is now | 344 // The input text is being changed, so any autofilled password is now |
| 329 // outdated. | 345 // outdated. |
| 330 blink::WebInputElement username = element; // We need a non-const. | 346 mutable_element.setAutofilled(false); |
| 331 username.setAutofilled(false); | 347 iter->second.wait_for_username_change = false; |
| 332 | 348 |
| 333 blink::WebInputElement password = iter->second.password_field; | 349 blink::WebInputElement password = iter->second.password_field; |
| 334 if (password.isAutofilled()) { | 350 if (password.isAutofilled()) { |
| 335 password.setValue(base::string16(), true); | 351 password.setValue(base::string16(), true); |
| 336 password.setAutofilled(false); | 352 password.setAutofilled(false); |
| 337 } | 353 } |
| 338 | 354 |
| 339 // If wait_for_username is true we will fill when the username loses focus. | 355 // If wait_for_username is true we will fill when the username loses focus. |
| 340 if (iter->second.fill_data.wait_for_username) | 356 if (iter->second.fill_data.wait_for_username) |
| 341 return false; | 357 return false; |
| 342 | 358 |
| 343 if (!element.isText() || !IsElementAutocompletable(element) || | 359 if (!element.isText() || !IsElementAutocompletable(element) || |
| 344 !IsElementAutocompletable(password)) { | 360 !IsElementAutocompletable(password)) { |
| 345 return false; | 361 return false; |
| 346 } | 362 } |
| 347 | 363 |
| 348 // Don't inline autocomplete if the user is deleting, that would be confusing. | 364 // Don't inline autocomplete if the user is deleting, that would be confusing. |
| 349 // But refresh the popup. Note, since this is ours, return true to signal | 365 // But refresh the popup. Note, since this is ours, return true to signal |
| 350 // no further processing is required. | 366 // no further processing is required. |
| 351 if (iter->second.backspace_pressed_last) { | 367 if (iter->second.backspace_pressed_last) { |
| 352 ShowSuggestionPopup(iter->second.fill_data, username, false); | 368 ShowSuggestionPopup(iter->second.fill_data, element, false); |
| 353 return true; | 369 return true; |
| 354 } | 370 } |
| 355 | 371 |
| 356 blink::WebString name = element.nameForAutofill(); | 372 blink::WebString name = element.nameForAutofill(); |
| 357 if (name.isEmpty()) | 373 if (name.isEmpty()) |
| 358 return false; // If the field has no name, then we won't have values. | 374 return false; // If the field has no name, then we won't have values. |
| 359 | 375 |
| 360 // Don't attempt to autofill with values that are too large. | 376 // Don't attempt to autofill with values that are too large. |
| 361 if (element.value().length() > kMaximumTextSizeForAutocomplete) | 377 if (element.value().length() > kMaximumTextSizeForAutocomplete) |
| 362 return false; | 378 return false; |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 381 iter->second.backspace_pressed_last = | 397 iter->second.backspace_pressed_last = |
| 382 (win_key_code == ui::VKEY_BACK || win_key_code == ui::VKEY_DELETE); | 398 (win_key_code == ui::VKEY_BACK || win_key_code == ui::VKEY_DELETE); |
| 383 return true; | 399 return true; |
| 384 } | 400 } |
| 385 | 401 |
| 386 bool PasswordAutofillAgent::FillSuggestion( | 402 bool PasswordAutofillAgent::FillSuggestion( |
| 387 const blink::WebNode& node, | 403 const blink::WebNode& node, |
| 388 const blink::WebString& username, | 404 const blink::WebString& username, |
| 389 const blink::WebString& password) { | 405 const blink::WebString& password) { |
| 390 blink::WebInputElement username_element; | 406 blink::WebInputElement username_element; |
| 391 PasswordInfo password_info; | 407 PasswordInfo* password_info; |
| 392 | 408 |
| 393 if (!FindLoginInfo(node, &username_element, &password_info) || | 409 if (!FindLoginInfo(node, &username_element, &password_info) || |
| 394 !IsElementAutocompletable(username_element) || | 410 !IsElementAutocompletable(username_element) || |
| 395 !IsElementAutocompletable(password_info.password_field)) { | 411 !IsElementAutocompletable(password_info->password_field)) { |
| 396 return false; | 412 return false; |
| 397 } | 413 } |
| 398 | 414 |
| 399 base::string16 current_username = username_element.value(); | 415 if (username_element.value() != username_element.value()) |
|
engedy
2014/08/06 10:18:17
If we are overwriting the password nevertheless, w
vabr (Chromium)
2014/08/25 14:53:29
Good catch!
Agreed and done.
| |
| 416 password_info->wait_for_username_change = false; | |
| 400 username_element.setValue(username, true); | 417 username_element.setValue(username, true); |
| 401 username_element.setAutofilled(true); | 418 username_element.setAutofilled(true); |
| 402 username_element.setSelectionRange(username.length(), username.length()); | 419 username_element.setSelectionRange(username.length(), username.length()); |
| 403 | 420 |
| 404 password_info.password_field.setValue(password, true); | 421 password_info->password_field.setValue(password, true); |
| 405 password_info.password_field.setAutofilled(true); | 422 password_info->password_field.setAutofilled(true); |
| 406 | 423 |
| 407 return true; | 424 return true; |
| 408 } | 425 } |
| 409 | 426 |
| 410 bool PasswordAutofillAgent::PreviewSuggestion( | 427 bool PasswordAutofillAgent::PreviewSuggestion( |
| 411 const blink::WebNode& node, | 428 const blink::WebNode& node, |
| 412 const blink::WebString& username, | 429 const blink::WebString& username, |
| 413 const blink::WebString& password) { | 430 const blink::WebString& password) { |
| 414 blink::WebInputElement username_element; | 431 blink::WebInputElement username_element; |
| 415 PasswordInfo password_info; | 432 PasswordInfo* password_info; |
| 416 | 433 |
| 417 if (!FindLoginInfo(node, &username_element, &password_info) || | 434 if (!FindLoginInfo(node, &username_element, &password_info) || |
| 418 !IsElementAutocompletable(username_element) || | 435 !IsElementAutocompletable(username_element) || |
| 419 !IsElementAutocompletable(password_info.password_field)) { | 436 !IsElementAutocompletable(password_info->password_field)) { |
| 420 return false; | 437 return false; |
| 421 } | 438 } |
| 422 | 439 |
| 423 was_username_autofilled_ = username_element.isAutofilled(); | 440 was_username_autofilled_ = username_element.isAutofilled(); |
| 424 username_selection_start_ = username_element.selectionStart(); | 441 username_selection_start_ = username_element.selectionStart(); |
| 425 username_element.setSuggestedValue(username); | 442 username_element.setSuggestedValue(username); |
| 426 username_element.setAutofilled(true); | 443 username_element.setAutofilled(true); |
| 427 username_element.setSelectionRange( | 444 username_element.setSelectionRange( |
| 428 username_selection_start_, | 445 username_selection_start_, |
| 429 username_element.suggestedValue().length()); | 446 username_element.suggestedValue().length()); |
| 430 | 447 |
| 431 was_password_autofilled_ = password_info.password_field.isAutofilled(); | 448 was_password_autofilled_ = password_info->password_field.isAutofilled(); |
| 432 password_info.password_field.setSuggestedValue(password); | 449 password_info->password_field.setSuggestedValue(password); |
| 433 password_info.password_field.setAutofilled(true); | 450 password_info->password_field.setAutofilled(true); |
| 434 | 451 |
| 435 return true; | 452 return true; |
| 436 } | 453 } |
| 437 | 454 |
| 438 bool PasswordAutofillAgent::DidClearAutofillSelection( | 455 bool PasswordAutofillAgent::DidClearAutofillSelection( |
| 439 const blink::WebNode& node) { | 456 const blink::WebNode& node) { |
| 440 blink::WebInputElement username_element; | 457 blink::WebInputElement username_element; |
| 441 PasswordInfo password_info; | 458 PasswordInfo* password_info; |
| 442 if (!FindLoginInfo(node, &username_element, &password_info)) | 459 if (!FindLoginInfo(node, &username_element, &password_info)) |
| 443 return false; | 460 return false; |
| 444 | 461 |
| 445 ClearPreview(&username_element, &password_info.password_field); | 462 ClearPreview(&username_element, &password_info->password_field); |
| 446 return true; | 463 return true; |
| 447 } | 464 } |
| 448 | 465 |
| 449 bool PasswordAutofillAgent::ShowSuggestions( | 466 bool PasswordAutofillAgent::ShowSuggestions( |
| 450 const blink::WebInputElement& element, | 467 const blink::WebInputElement& element, |
| 451 bool show_all) { | 468 bool show_all) { |
| 452 LoginToPasswordInfoMap::const_iterator iter = | 469 LoginToPasswordInfoMap::const_iterator iter = |
| 453 login_to_password_info_.find(element); | 470 login_to_password_info_.find(element); |
| 454 if (iter == login_to_password_info_.end()) | 471 if (iter == login_to_password_info_.end()) |
| 455 return false; | 472 return false; |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 804 // We might have already filled this form if there are two <form> elements | 821 // We might have already filled this form if there are two <form> elements |
| 805 // with identical markup. | 822 // with identical markup. |
| 806 if (login_to_password_info_.find(username_element) != | 823 if (login_to_password_info_.find(username_element) != |
| 807 login_to_password_info_.end()) | 824 login_to_password_info_.end()) |
| 808 continue; | 825 continue; |
| 809 | 826 |
| 810 PasswordInfo password_info; | 827 PasswordInfo password_info; |
| 811 password_info.fill_data = form_data; | 828 password_info.fill_data = form_data; |
| 812 password_info.password_field = password_element; | 829 password_info.password_field = password_element; |
| 813 login_to_password_info_[username_element] = password_info; | 830 login_to_password_info_[username_element] = password_info; |
| 831 password_to_username_[password_element] = username_element; | |
| 814 | 832 |
| 815 FormData form; | 833 FormData form; |
| 816 FormFieldData field; | 834 FormFieldData field; |
| 817 FindFormAndFieldForFormControlElement( | 835 FindFormAndFieldForFormControlElement( |
| 818 username_element, &form, &field, REQUIRE_NONE); | 836 username_element, &form, &field, REQUIRE_NONE); |
| 819 Send(new AutofillHostMsg_AddPasswordFormMapping( | 837 Send(new AutofillHostMsg_AddPasswordFormMapping( |
| 820 routing_id(), field, form_data)); | 838 routing_id(), field, form_data)); |
| 821 } | 839 } |
| 822 } | 840 } |
| 823 | 841 |
| 824 void PasswordAutofillAgent::OnSetLoggingState(bool active) { | 842 void PasswordAutofillAgent::OnSetLoggingState(bool active) { |
| 825 logging_state_active_ = active; | 843 logging_state_active_ = active; |
| 826 } | 844 } |
| 827 | 845 |
| 828 //////////////////////////////////////////////////////////////////////////////// | 846 //////////////////////////////////////////////////////////////////////////////// |
| 829 // PasswordAutofillAgent, private: | 847 // PasswordAutofillAgent, private: |
| 830 | 848 |
| 849 PasswordAutofillAgent::PasswordInfo::PasswordInfo() | |
| 850 : backspace_pressed_last(false), wait_for_username_change(false) { | |
| 851 } | |
| 852 | |
| 831 void PasswordAutofillAgent::GetSuggestions( | 853 void PasswordAutofillAgent::GetSuggestions( |
| 832 const PasswordFormFillData& fill_data, | 854 const PasswordFormFillData& fill_data, |
| 833 const base::string16& input, | 855 const base::string16& input, |
| 834 std::vector<base::string16>* suggestions, | 856 std::vector<base::string16>* suggestions, |
| 835 std::vector<base::string16>* realms, | 857 std::vector<base::string16>* realms, |
| 836 bool show_all) { | 858 bool show_all) { |
| 837 if (show_all || | 859 if (show_all || |
| 838 StartsWith(fill_data.basic_data.fields[0].value, input, false)) { | 860 StartsWith(fill_data.basic_data.fields[0].value, input, false)) { |
| 839 suggestions->push_back(fill_data.basic_data.fields[0].value); | 861 suggestions->push_back(fill_data.basic_data.fields[0].value); |
| 840 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); | 862 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); |
| (...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1048 &password, | 1070 &password, |
| 1049 fill_data, | 1071 fill_data, |
| 1050 false /* exact_username_match */, | 1072 false /* exact_username_match */, |
| 1051 true /* set_selection */); | 1073 true /* set_selection */); |
| 1052 #endif | 1074 #endif |
| 1053 } | 1075 } |
| 1054 | 1076 |
| 1055 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { | 1077 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { |
| 1056 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); | 1078 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
| 1057 iter != login_to_password_info_.end();) { | 1079 iter != login_to_password_info_.end();) { |
| 1058 if (iter->first.document().frame() == frame) | 1080 if (iter->first.document().frame() == frame) { |
| 1081 password_to_username_.erase(iter->second.password_field); | |
| 1059 login_to_password_info_.erase(iter++); | 1082 login_to_password_info_.erase(iter++); |
| 1060 else | 1083 } else { |
| 1061 ++iter; | 1084 ++iter; |
| 1085 } | |
| 1062 } | 1086 } |
| 1063 for (FrameToPasswordFormMap::iterator iter = | 1087 for (FrameToPasswordFormMap::iterator iter = |
| 1064 provisionally_saved_forms_.begin(); | 1088 provisionally_saved_forms_.begin(); |
| 1065 iter != provisionally_saved_forms_.end();) { | 1089 iter != provisionally_saved_forms_.end();) { |
| 1066 if (iter->first == frame) | 1090 if (iter->first == frame) |
| 1067 provisionally_saved_forms_.erase(iter++); | 1091 provisionally_saved_forms_.erase(iter++); |
| 1068 else | 1092 else |
| 1069 ++iter; | 1093 ++iter; |
| 1070 } | 1094 } |
| 1071 } | 1095 } |
| 1072 | 1096 |
| 1073 bool PasswordAutofillAgent::FindLoginInfo(const blink::WebNode& node, | 1097 bool PasswordAutofillAgent::FindLoginInfo(const blink::WebNode& node, |
| 1074 blink::WebInputElement* found_input, | 1098 blink::WebInputElement* found_input, |
| 1075 PasswordInfo* found_password) { | 1099 PasswordInfo** found_password) { |
| 1076 if (!node.isElementNode()) | 1100 if (!node.isElementNode()) |
| 1077 return false; | 1101 return false; |
| 1078 | 1102 |
| 1079 blink::WebElement element = node.toConst<blink::WebElement>(); | 1103 blink::WebElement element = node.toConst<blink::WebElement>(); |
| 1080 if (!element.hasHTMLTagName("input")) | 1104 if (!element.hasHTMLTagName("input")) |
| 1081 return false; | 1105 return false; |
| 1082 | 1106 |
| 1083 blink::WebInputElement input = element.to<blink::WebInputElement>(); | 1107 blink::WebInputElement input = element.to<blink::WebInputElement>(); |
| 1084 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); | 1108 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); |
| 1085 if (iter == login_to_password_info_.end()) | 1109 if (iter == login_to_password_info_.end()) |
| 1086 return false; | 1110 return false; |
| 1087 | 1111 |
| 1088 *found_input = input; | 1112 *found_input = input; |
| 1089 *found_password = iter->second; | 1113 *found_password = &iter->second; |
| 1090 return true; | 1114 return true; |
| 1091 } | 1115 } |
| 1092 | 1116 |
| 1093 void PasswordAutofillAgent::ClearPreview( | 1117 void PasswordAutofillAgent::ClearPreview( |
| 1094 blink::WebInputElement* username, | 1118 blink::WebInputElement* username, |
| 1095 blink::WebInputElement* password) { | 1119 blink::WebInputElement* password) { |
| 1096 if (!username->suggestedValue().isEmpty()) { | 1120 if (!username->suggestedValue().isEmpty()) { |
| 1097 username->setSuggestedValue(blink::WebString()); | 1121 username->setSuggestedValue(blink::WebString()); |
| 1098 username->setAutofilled(was_username_autofilled_); | 1122 username->setAutofilled(was_username_autofilled_); |
| 1099 username->setSelectionRange(username_selection_start_, | 1123 username->setSelectionRange(username_selection_start_, |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1113 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form)); | 1137 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form)); |
| 1114 if (!password_form || (restriction == RESTRICTION_NON_EMPTY_PASSWORD && | 1138 if (!password_form || (restriction == RESTRICTION_NON_EMPTY_PASSWORD && |
| 1115 password_form->password_value.empty() && | 1139 password_form->password_value.empty() && |
| 1116 password_form->new_password_value.empty())) { | 1140 password_form->new_password_value.empty())) { |
| 1117 return; | 1141 return; |
| 1118 } | 1142 } |
| 1119 provisionally_saved_forms_[frame].reset(password_form.release()); | 1143 provisionally_saved_forms_[frame].reset(password_form.release()); |
| 1120 } | 1144 } |
| 1121 | 1145 |
| 1122 } // namespace autofill | 1146 } // namespace autofill |
| OLD | NEW |