| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <string> | 10 #include <string> |
| 11 #include <utility> | 11 #include <utility> |
| 12 | 12 |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/i18n/case_conversion.h" | 14 #include "base/i18n/case_conversion.h" |
| 15 #include "base/memory/linked_ptr.h" | 15 #include "base/memory/linked_ptr.h" |
| 16 #include "base/message_loop/message_loop.h" | 16 #include "base/message_loop/message_loop.h" |
| 17 #include "base/metrics/histogram_macros.h" | 17 #include "base/metrics/histogram_macros.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 19 #include "build/build_config.h" | 19 #include "build/build_config.h" |
| 20 #include "components/autofill/content/common/autofill_messages.h" | 20 #include "components/autofill/content/common/autofill_messages.h" |
| 21 #include "components/autofill/content/renderer/form_autofill_util.h" | 21 #include "components/autofill/content/renderer/form_autofill_util.h" |
| 22 #include "components/autofill/content/renderer/password_form_conversion_utils.h" | 22 #include "components/autofill/content/renderer/password_form_conversion_utils.h" |
| 23 #include "components/autofill/content/renderer/renderer_save_password_progress_l
ogger.h" | 23 #include "components/autofill/content/renderer/renderer_save_password_progress_l
ogger.h" |
| 24 #include "components/autofill/core/common/autofill_constants.h" | 24 #include "components/autofill/core/common/autofill_constants.h" |
| 25 #include "components/autofill/core/common/autofill_util.h" | 25 #include "components/autofill/core/common/autofill_util.h" |
| 26 #include "components/autofill/core/common/form_field_data.h" | 26 #include "components/autofill/core/common/form_field_data.h" |
| 27 #include "components/autofill/core/common/password_form.h" | |
| 28 #include "components/autofill/core/common/password_form_fill_data.h" | 27 #include "components/autofill/core/common/password_form_fill_data.h" |
| 29 #include "content/public/renderer/document_state.h" | 28 #include "content/public/renderer/document_state.h" |
| 30 #include "content/public/renderer/navigation_state.h" | 29 #include "content/public/renderer/navigation_state.h" |
| 31 #include "content/public/renderer/render_frame.h" | 30 #include "content/public/renderer/render_frame.h" |
| 32 #include "content/public/renderer/render_view.h" | 31 #include "content/public/renderer/render_view.h" |
| 33 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" | 32 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" |
| 34 #include "third_party/WebKit/public/platform/WebVector.h" | 33 #include "third_party/WebKit/public/platform/WebVector.h" |
| 35 #include "third_party/WebKit/public/web/WebAutofillClient.h" | 34 #include "third_party/WebKit/public/web/WebAutofillClient.h" |
| 36 #include "third_party/WebKit/public/web/WebDocument.h" | 35 #include "third_party/WebKit/public/web/WebDocument.h" |
| 37 #include "third_party/WebKit/public/web/WebElement.h" | 36 #include "third_party/WebKit/public/web/WebElement.h" |
| (...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 342 base::StartsWith(base::i18n::ToLower(login.first), | 341 base::StartsWith(base::i18n::ToLower(login.first), |
| 343 current_username_lower, | 342 current_username_lower, |
| 344 base::CompareCase::SENSITIVE)) { | 343 base::CompareCase::SENSITIVE)) { |
| 345 return true; | 344 return true; |
| 346 } | 345 } |
| 347 } | 346 } |
| 348 | 347 |
| 349 return false; | 348 return false; |
| 350 } | 349 } |
| 351 | 350 |
| 351 // Updates the value (i.e. the pair of elements's value |value| and field |
| 352 // properties |added_flags|) associated with the key |element| in |
| 353 // |field_value_and_properties_map|. |
| 354 // Flags in |added_flags| are added with bitwise OR operation. |
| 355 // If |value| is null, the value isn't updated. |
| 356 void UpdateFieldValueAndPropertiesMaskMap( |
| 357 const blink::WebFormControlElement& element, |
| 358 const base::string16* value, |
| 359 FieldPropertiesMask added_flags, |
| 360 FieldValueAndPropertiesMaskMap* field_value_and_properties_map) { |
| 361 FieldValueAndPropertiesMaskMap::iterator it = |
| 362 field_value_and_properties_map->find(element); |
| 363 if (it != field_value_and_properties_map->end()) { |
| 364 if (value) |
| 365 it->second.first = *value; |
| 366 it->second.second |= added_flags; |
| 367 } else { |
| 368 (*field_value_and_properties_map)[element] = |
| 369 std::make_pair(value ? *value : base::string16(), added_flags); |
| 370 } |
| 371 } |
| 372 |
| 352 // This function attempts to fill |username_element| and |password_element| | 373 // This function attempts to fill |username_element| and |password_element| |
| 353 // with values from |fill_data|. The |password_element| will only have the | 374 // with values from |fill_data|. The |password_element| will only have the |
| 354 // suggestedValue set, and will be registered for copying that to the real | 375 // suggestedValue set, and will be registered for copying that to the real |
| 355 // value through |registration_callback|. If a match is found, return true and | 376 // value through |registration_callback|. If a match is found, return true and |
| 356 // |nonscript_modified_values| will be modified with the autofilled credentials. | 377 // |field_value_and_properties_map| will be modified with the autofilled |
| 378 // credentials and |FieldPropertiesFlags::AUTOFILLED| flag. |
| 357 bool FillUserNameAndPassword( | 379 bool FillUserNameAndPassword( |
| 358 blink::WebInputElement* username_element, | 380 blink::WebInputElement* username_element, |
| 359 blink::WebInputElement* password_element, | 381 blink::WebInputElement* password_element, |
| 360 const PasswordFormFillData& fill_data, | 382 const PasswordFormFillData& fill_data, |
| 361 bool exact_username_match, | 383 bool exact_username_match, |
| 362 bool set_selection, | 384 bool set_selection, |
| 363 std::map<const blink::WebInputElement, blink::WebString>* | 385 FieldValueAndPropertiesMaskMap* field_value_and_properties_map, |
| 364 nonscript_modified_values, | |
| 365 base::Callback<void(blink::WebInputElement*)> registration_callback, | 386 base::Callback<void(blink::WebInputElement*)> registration_callback, |
| 366 RendererSavePasswordProgressLogger* logger) { | 387 RendererSavePasswordProgressLogger* logger) { |
| 367 if (logger) | 388 if (logger) |
| 368 logger->LogMessage(Logger::STRING_FILL_USERNAME_AND_PASSWORD_METHOD); | 389 logger->LogMessage(Logger::STRING_FILL_USERNAME_AND_PASSWORD_METHOD); |
| 369 | 390 |
| 370 // Don't fill username if password can't be set. | 391 // Don't fill username if password can't be set. |
| 371 if (!IsElementAutocompletable(*password_element)) | 392 if (!IsElementAutocompletable(*password_element)) |
| 372 return false; | 393 return false; |
| 373 | 394 |
| 374 base::string16 current_username; | 395 base::string16 current_username; |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 return false; | 442 return false; |
| 422 | 443 |
| 423 // TODO(tkent): Check maxlength and pattern for both username and password | 444 // TODO(tkent): Check maxlength and pattern for both username and password |
| 424 // fields. | 445 // fields. |
| 425 | 446 |
| 426 // Input matches the username, fill in required values. | 447 // Input matches the username, fill in required values. |
| 427 if (!username_element->isNull() && | 448 if (!username_element->isNull() && |
| 428 IsElementAutocompletable(*username_element)) { | 449 IsElementAutocompletable(*username_element)) { |
| 429 // TODO(crbug.com/507714): Why not setSuggestedValue? | 450 // TODO(crbug.com/507714): Why not setSuggestedValue? |
| 430 username_element->setValue(username, true); | 451 username_element->setValue(username, true); |
| 431 (*nonscript_modified_values)[*username_element] = username; | 452 UpdateFieldValueAndPropertiesMaskMap(*username_element, &username, |
| 453 FieldPropertiesFlags::AUTOFILLED, |
| 454 field_value_and_properties_map); |
| 432 username_element->setAutofilled(true); | 455 username_element->setAutofilled(true); |
| 433 if (logger) | 456 if (logger) |
| 434 logger->LogElementName(Logger::STRING_USERNAME_FILLED, *username_element); | 457 logger->LogElementName(Logger::STRING_USERNAME_FILLED, *username_element); |
| 435 if (set_selection) { | 458 if (set_selection) { |
| 436 form_util::PreviewSuggestion(username, current_username, | 459 form_util::PreviewSuggestion(username, current_username, |
| 437 username_element); | 460 username_element); |
| 438 } | 461 } |
| 439 } else if (current_username != username) { | 462 } else if (current_username != username) { |
| 440 // If the username can't be filled and it doesn't match a saved password | 463 // If the username can't be filled and it doesn't match a saved password |
| 441 // as is, don't autofill a password. | 464 // as is, don't autofill a password. |
| 442 return false; | 465 return false; |
| 443 } | 466 } |
| 444 | 467 |
| 445 // Wait to fill in the password until a user gesture occurs. This is to make | 468 // Wait to fill in the password until a user gesture occurs. This is to make |
| 446 // sure that we do not fill in the DOM with a password until we believe the | 469 // sure that we do not fill in the DOM with a password until we believe the |
| 447 // user is intentionally interacting with the page. | 470 // user is intentionally interacting with the page. |
| 448 password_element->setSuggestedValue(password); | 471 password_element->setSuggestedValue(password); |
| 449 (*nonscript_modified_values)[*password_element] = password; | 472 UpdateFieldValueAndPropertiesMaskMap(*password_element, &password, |
| 473 FieldPropertiesFlags::AUTOFILLED, |
| 474 field_value_and_properties_map); |
| 450 registration_callback.Run(password_element); | 475 registration_callback.Run(password_element); |
| 451 | 476 |
| 452 password_element->setAutofilled(true); | 477 password_element->setAutofilled(true); |
| 453 if (logger) | 478 if (logger) |
| 454 logger->LogElementName(Logger::STRING_PASSWORD_FILLED, *password_element); | 479 logger->LogElementName(Logger::STRING_PASSWORD_FILLED, *password_element); |
| 455 return true; | 480 return true; |
| 456 } | 481 } |
| 457 | 482 |
| 458 // Attempts to fill |username_element| and |password_element| with the | 483 // Attempts to fill |username_element| and |password_element| with the |
| 459 // |fill_data|. Will use the data corresponding to the preferred username, | 484 // |fill_data|. Will use the data corresponding to the preferred username, |
| 460 // unless the |username_element| already has a value set. In that case, | 485 // unless the |username_element| already has a value set. In that case, |
| 461 // attempts to fill the password matching the already filled username, if | 486 // attempts to fill the password matching the already filled username, if |
| 462 // such a password exists. The |password_element| will have the | 487 // such a password exists. The |password_element| will have the |
| 463 // |suggestedValue| set, and |suggestedValue| will be registered for copying to | 488 // |suggestedValue| set, and |suggestedValue| will be registered for copying to |
| 464 // the real value through |registration_callback|. Returns true if the password | 489 // the real value through |registration_callback|. Returns true if the password |
| 465 // is filled. | 490 // is filled. |
| 466 bool FillFormOnPasswordReceived( | 491 bool FillFormOnPasswordReceived( |
| 467 const PasswordFormFillData& fill_data, | 492 const PasswordFormFillData& fill_data, |
| 468 blink::WebInputElement username_element, | 493 blink::WebInputElement username_element, |
| 469 blink::WebInputElement password_element, | 494 blink::WebInputElement password_element, |
| 470 std::map<const blink::WebInputElement, blink::WebString>* | 495 FieldValueAndPropertiesMaskMap* field_value_and_properties_map, |
| 471 nonscript_modified_values, | |
| 472 base::Callback<void(blink::WebInputElement*)> registration_callback, | 496 base::Callback<void(blink::WebInputElement*)> registration_callback, |
| 473 RendererSavePasswordProgressLogger* logger) { | 497 RendererSavePasswordProgressLogger* logger) { |
| 474 // Do not fill if the password field is in a chain of iframes not having | 498 // Do not fill if the password field is in a chain of iframes not having |
| 475 // identical origin. | 499 // identical origin. |
| 476 blink::WebFrame* cur_frame = password_element.document().frame(); | 500 blink::WebFrame* cur_frame = password_element.document().frame(); |
| 477 blink::WebString bottom_frame_origin = | 501 blink::WebString bottom_frame_origin = |
| 478 cur_frame->getSecurityOrigin().toString(); | 502 cur_frame->getSecurityOrigin().toString(); |
| 479 | 503 |
| 480 DCHECK(cur_frame); | 504 DCHECK(cur_frame); |
| 481 | 505 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 520 if (form_has_fillable_username && username_element.value().isEmpty()) { | 544 if (form_has_fillable_username && username_element.value().isEmpty()) { |
| 521 // TODO(tkent): Check maxlength and pattern. | 545 // TODO(tkent): Check maxlength and pattern. |
| 522 username_element.setValue(fill_data.username_field.value, true); | 546 username_element.setValue(fill_data.username_field.value, true); |
| 523 } | 547 } |
| 524 | 548 |
| 525 // Fill if we have an exact match for the username. Note that this sets | 549 // Fill if we have an exact match for the username. Note that this sets |
| 526 // username to autofilled. | 550 // username to autofilled. |
| 527 return FillUserNameAndPassword( | 551 return FillUserNameAndPassword( |
| 528 &username_element, &password_element, fill_data, | 552 &username_element, &password_element, fill_data, |
| 529 true /* exact_username_match */, false /* set_selection */, | 553 true /* exact_username_match */, false /* set_selection */, |
| 530 nonscript_modified_values, registration_callback, logger); | 554 field_value_and_properties_map, registration_callback, logger); |
| 531 } | 555 } |
| 532 | 556 |
| 533 // Takes a |map| with pointers as keys and linked_ptr as values, and returns | 557 // Takes a |map| with pointers as keys and linked_ptr as values, and returns |
| 534 // true if |key| is not NULL and |map| contains a non-NULL entry for |key|. | 558 // true if |key| is not NULL and |map| contains a non-NULL entry for |key|. |
| 535 // Makes sure not to create an entry as a side effect of using the operator []. | 559 // Makes sure not to create an entry as a side effect of using the operator []. |
| 536 template <class Key, class Value> | 560 template <class Key, class Value> |
| 537 bool ContainsNonNullEntryForNonNullKey( | 561 bool ContainsNonNullEntryForNonNullKey( |
| 538 const std::map<Key*, linked_ptr<Value>>& map, | 562 const std::map<Key*, linked_ptr<Value>>& map, |
| 539 Key* key) { | 563 Key* key) { |
| 540 if (!key) | 564 if (!key) |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 618 | 642 |
| 619 blink::WebInputElement password = password_info.password_field; | 643 blink::WebInputElement password = password_info.password_field; |
| 620 if (!IsElementEditable(password)) | 644 if (!IsElementEditable(password)) |
| 621 return false; | 645 return false; |
| 622 | 646 |
| 623 blink::WebInputElement username = element; // We need a non-const. | 647 blink::WebInputElement username = element; // We need a non-const. |
| 624 | 648 |
| 625 // Do not set selection when ending an editing session, otherwise it can | 649 // Do not set selection when ending an editing session, otherwise it can |
| 626 // mess with focus. | 650 // mess with focus. |
| 627 FillUserNameAndPassword(&username, &password, fill_data, true, false, | 651 FillUserNameAndPassword(&username, &password, fill_data, true, false, |
| 628 &nonscript_modified_values_, | 652 &field_value_and_properties_map_, |
| 629 base::Bind(&PasswordValueGatekeeper::RegisterElement, | 653 base::Bind(&PasswordValueGatekeeper::RegisterElement, |
| 630 base::Unretained(&gatekeeper_)), | 654 base::Unretained(&gatekeeper_)), |
| 631 nullptr); | 655 nullptr); |
| 632 return true; | 656 return true; |
| 633 } | 657 } |
| 634 | 658 |
| 635 bool PasswordAutofillAgent::TextDidChangeInTextField( | 659 bool PasswordAutofillAgent::TextDidChangeInTextField( |
| 636 const blink::WebInputElement& element) { | 660 const blink::WebInputElement& element) { |
| 637 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 | 661 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 |
| 638 blink::WebInputElement mutable_element = element; // We need a non-const. | 662 blink::WebInputElement mutable_element = element; // We need a non-const. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 649 | 673 |
| 650 // Show the popup with the list of available usernames. | 674 // Show the popup with the list of available usernames. |
| 651 return ShowSuggestions(element, false, false); | 675 return ShowSuggestions(element, false, false); |
| 652 } | 676 } |
| 653 | 677 |
| 654 void PasswordAutofillAgent::UpdateStateForTextChange( | 678 void PasswordAutofillAgent::UpdateStateForTextChange( |
| 655 const blink::WebInputElement& element) { | 679 const blink::WebInputElement& element) { |
| 656 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 | 680 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 |
| 657 blink::WebInputElement mutable_element = element; // We need a non-const. | 681 blink::WebInputElement mutable_element = element; // We need a non-const. |
| 658 | 682 |
| 659 if (element.isTextField()) | 683 if (element.isTextField()) { |
| 660 nonscript_modified_values_[element] = element.value(); | 684 const base::string16 element_value = element.value(); |
| 685 UpdateFieldValueAndPropertiesMaskMap(element, &element_value, |
| 686 FieldPropertiesFlags::USER_TYPED, |
| 687 &field_value_and_properties_map_); |
| 688 } |
| 661 | 689 |
| 662 blink::WebFrame* const element_frame = element.document().frame(); | 690 blink::WebFrame* const element_frame = element.document().frame(); |
| 663 // The element's frame might have been detached in the meantime (see | 691 // The element's frame might have been detached in the meantime (see |
| 664 // http://crbug.com/585363, comments 5 and 6), in which case frame() will | 692 // http://crbug.com/585363, comments 5 and 6), in which case frame() will |
| 665 // return null. This was hardly caused by form submission (unless the user | 693 // return null. This was hardly caused by form submission (unless the user |
| 666 // is supernaturally quick), so it is OK to drop the ball here. | 694 // is supernaturally quick), so it is OK to drop the ball here. |
| 667 if (!element_frame) | 695 if (!element_frame) |
| 668 return; | 696 return; |
| 669 DCHECK_EQ(element_frame, render_frame()->GetWebFrame()); | 697 DCHECK_EQ(element_frame, render_frame()->GetWebFrame()); |
| 670 | 698 |
| 671 // Some login forms have event handlers that put a hash of the password into | 699 // Some login forms have event handlers that put a hash of the password into |
| 672 // a hidden field and then clear the password (http://crbug.com/28910, | 700 // a hidden field and then clear the password (http://crbug.com/28910, |
| 673 // http://crbug.com/391693). This method gets called before any of those | 701 // http://crbug.com/391693). This method gets called before any of those |
| 674 // handlers run, so save away a copy of the password in case it gets lost. | 702 // handlers run, so save away a copy of the password in case it gets lost. |
| 675 // To honor the user having explicitly cleared the password, even an empty | 703 // To honor the user having explicitly cleared the password, even an empty |
| 676 // password will be saved here. | 704 // password will be saved here. |
| 677 std::unique_ptr<PasswordForm> password_form; | 705 std::unique_ptr<PasswordForm> password_form; |
| 678 if (element.form().isNull()) { | 706 if (element.form().isNull()) { |
| 679 password_form = CreatePasswordFormFromUnownedInputElements( | 707 password_form = CreatePasswordFormFromUnownedInputElements( |
| 680 *element_frame, &nonscript_modified_values_, &form_predictions_); | 708 *element_frame, &field_value_and_properties_map_, &form_predictions_); |
| 681 } else { | 709 } else { |
| 682 password_form = CreatePasswordFormFromWebForm( | 710 password_form = CreatePasswordFormFromWebForm( |
| 683 element.form(), &nonscript_modified_values_, &form_predictions_); | 711 element.form(), &field_value_and_properties_map_, &form_predictions_); |
| 684 } | 712 } |
| 685 ProvisionallySavePassword(std::move(password_form), RESTRICTION_NONE); | 713 ProvisionallySavePassword(std::move(password_form), RESTRICTION_NONE); |
| 686 | 714 |
| 687 if (element.isPasswordField()) { | 715 if (element.isPasswordField()) { |
| 688 PasswordToLoginMap::iterator iter = password_to_username_.find(element); | 716 PasswordToLoginMap::iterator iter = password_to_username_.find(element); |
| 689 if (iter != password_to_username_.end()) { | 717 if (iter != password_to_username_.end()) { |
| 690 web_input_to_password_info_[iter->second].password_was_edited_last = true; | 718 web_input_to_password_info_[iter->second].password_was_edited_last = true; |
| 691 // Note that the suggested value of |mutable_element| was reset when its | 719 // Note that the suggested value of |mutable_element| was reset when its |
| 692 // value changed. | 720 // value changed. |
| 693 mutable_element.setAutofilled(false); | 721 mutable_element.setAutofilled(false); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 716 return false; | 744 return false; |
| 717 } | 745 } |
| 718 | 746 |
| 719 password_info->password_was_edited_last = false; | 747 password_info->password_was_edited_last = false; |
| 720 if (element->isPasswordField()) { | 748 if (element->isPasswordField()) { |
| 721 password_info->password_field_suggestion_was_accepted = true; | 749 password_info->password_field_suggestion_was_accepted = true; |
| 722 password_info->password_field = password_element; | 750 password_info->password_field = password_element; |
| 723 } else if (!username_element.isNull()) { | 751 } else if (!username_element.isNull()) { |
| 724 username_element.setValue(username, true); | 752 username_element.setValue(username, true); |
| 725 username_element.setAutofilled(true); | 753 username_element.setAutofilled(true); |
| 726 nonscript_modified_values_[username_element] = username; | 754 const base::string16 username_value = username; |
| 755 UpdateFieldValueAndPropertiesMaskMap(username_element, &username_value, |
| 756 FieldPropertiesFlags::AUTOFILLED, |
| 757 &field_value_and_properties_map_); |
| 727 } | 758 } |
| 728 | 759 |
| 729 password_element.setValue(password, true); | 760 password_element.setValue(password, true); |
| 730 password_element.setAutofilled(true); | 761 password_element.setAutofilled(true); |
| 731 nonscript_modified_values_[password_element] = password; | 762 const base::string16 password_value = password; |
| 763 UpdateFieldValueAndPropertiesMaskMap(password_element, &password_value, |
| 764 FieldPropertiesFlags::AUTOFILLED, |
| 765 &field_value_and_properties_map_); |
| 732 | 766 |
| 733 blink::WebInputElement mutable_filled_element = *element; | 767 blink::WebInputElement mutable_filled_element = *element; |
| 734 mutable_filled_element.setSelectionRange(element->value().length(), | 768 mutable_filled_element.setSelectionRange(element->value().length(), |
| 735 element->value().length()); | 769 element->value().length()); |
| 736 | 770 |
| 737 return true; | 771 return true; |
| 738 } | 772 } |
| 739 | 773 |
| 740 bool PasswordAutofillAgent::PreviewSuggestion( | 774 bool PasswordAutofillAgent::PreviewSuggestion( |
| 741 const blink::WebFormControlElement& control_element, | 775 const blink::WebFormControlElement& control_element, |
| (...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1098 // | 1132 // |
| 1099 // User-typed password will get stored to |provisionally_saved_form_| in | 1133 // User-typed password will get stored to |provisionally_saved_form_| in |
| 1100 // TextDidChangeInTextField. Autofilled or JavaScript-copied passwords need to | 1134 // TextDidChangeInTextField. Autofilled or JavaScript-copied passwords need to |
| 1101 // be saved here. | 1135 // be saved here. |
| 1102 // | 1136 // |
| 1103 // Only non-empty passwords are saved here. Empty passwords were likely | 1137 // Only non-empty passwords are saved here. Empty passwords were likely |
| 1104 // cleared by some scripts (http://crbug.com/28910, http://crbug.com/391693). | 1138 // cleared by some scripts (http://crbug.com/28910, http://crbug.com/391693). |
| 1105 // Had the user cleared the password, |provisionally_saved_form_| would | 1139 // Had the user cleared the password, |provisionally_saved_form_| would |
| 1106 // already have been updated in TextDidChangeInTextField. | 1140 // already have been updated in TextDidChangeInTextField. |
| 1107 std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( | 1141 std::unique_ptr<PasswordForm> password_form = CreatePasswordFormFromWebForm( |
| 1108 form, &nonscript_modified_values_, &form_predictions_); | 1142 form, &field_value_and_properties_map_, &form_predictions_); |
| 1109 ProvisionallySavePassword(std::move(password_form), | 1143 ProvisionallySavePassword(std::move(password_form), |
| 1110 RESTRICTION_NON_EMPTY_PASSWORD); | 1144 RESTRICTION_NON_EMPTY_PASSWORD); |
| 1111 } | 1145 } |
| 1112 | 1146 |
| 1113 void PasswordAutofillAgent::WillSubmitForm(const blink::WebFormElement& form) { | 1147 void PasswordAutofillAgent::WillSubmitForm(const blink::WebFormElement& form) { |
| 1114 std::unique_ptr<RendererSavePasswordProgressLogger> logger; | 1148 std::unique_ptr<RendererSavePasswordProgressLogger> logger; |
| 1115 if (logging_state_active_) { | 1149 if (logging_state_active_) { |
| 1116 logger.reset(new RendererSavePasswordProgressLogger(this, routing_id())); | 1150 logger.reset(new RendererSavePasswordProgressLogger(this, routing_id())); |
| 1117 logger->LogMessage(Logger::STRING_WILL_SUBMIT_FORM_METHOD); | 1151 logger->LogMessage(Logger::STRING_WILL_SUBMIT_FORM_METHOD); |
| 1118 LogHTMLForm(logger.get(), Logger::STRING_HTML_FORM_FOR_SUBMIT, form); | 1152 LogHTMLForm(logger.get(), Logger::STRING_HTML_FORM_FOR_SUBMIT, form); |
| 1119 } | 1153 } |
| 1120 | 1154 |
| 1121 std::unique_ptr<PasswordForm> submitted_form = CreatePasswordFormFromWebForm( | 1155 std::unique_ptr<PasswordForm> submitted_form = CreatePasswordFormFromWebForm( |
| 1122 form, &nonscript_modified_values_, &form_predictions_); | 1156 form, &field_value_and_properties_map_, &form_predictions_); |
| 1123 | 1157 |
| 1124 // If there is a provisionally saved password, copy over the previous | 1158 // If there is a provisionally saved password, copy over the previous |
| 1125 // password value so we get the user's typed password, not the value that | 1159 // password value so we get the user's typed password, not the value that |
| 1126 // may have been transformed for submit. | 1160 // may have been transformed for submit. |
| 1127 // TODO(gcasto): Do we need to have this action equality check? Is it trying | 1161 // TODO(gcasto): Do we need to have this action equality check? Is it trying |
| 1128 // to prevent accidentally copying over passwords from a different form? | 1162 // to prevent accidentally copying over passwords from a different form? |
| 1129 if (submitted_form) { | 1163 if (submitted_form) { |
| 1130 if (logger) { | 1164 if (logger) { |
| 1131 logger->LogPasswordForm(Logger::STRING_CREATED_PASSWORD_FORM, | 1165 logger->LogPasswordForm(Logger::STRING_CREATED_PASSWORD_FORM, |
| 1132 *submitted_form); | 1166 *submitted_form); |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1203 render_frame()->GetWebFrame()->document().forms(forms); | 1237 render_frame()->GetWebFrame()->document().forms(forms); |
| 1204 | 1238 |
| 1205 bool password_forms_found = false; | 1239 bool password_forms_found = false; |
| 1206 for (size_t i = 0; i < forms.size(); ++i) { | 1240 for (size_t i = 0; i < forms.size(); ++i) { |
| 1207 blink::WebFormElement form_element = forms[i]; | 1241 blink::WebFormElement form_element = forms[i]; |
| 1208 if (logger) { | 1242 if (logger) { |
| 1209 LogHTMLForm(logger.get(), Logger::STRING_FORM_FOUND_ON_PAGE, | 1243 LogHTMLForm(logger.get(), Logger::STRING_FORM_FOUND_ON_PAGE, |
| 1210 form_element); | 1244 form_element); |
| 1211 } | 1245 } |
| 1212 possible_submitted_forms.push_back(CreatePasswordFormFromWebForm( | 1246 possible_submitted_forms.push_back(CreatePasswordFormFromWebForm( |
| 1213 form_element, &nonscript_modified_values_, &form_predictions_)); | 1247 form_element, &field_value_and_properties_map_, |
| 1248 &form_predictions_)); |
| 1214 } | 1249 } |
| 1215 | 1250 |
| 1216 possible_submitted_forms.push_back( | 1251 possible_submitted_forms.push_back( |
| 1217 CreatePasswordFormFromUnownedInputElements( | 1252 CreatePasswordFormFromUnownedInputElements( |
| 1218 *render_frame()->GetWebFrame(), | 1253 *render_frame()->GetWebFrame(), &field_value_and_properties_map_, |
| 1219 &nonscript_modified_values_, | |
| 1220 &form_predictions_)); | 1254 &form_predictions_)); |
| 1221 | 1255 |
| 1222 for (const PasswordForm* password_form : possible_submitted_forms) { | 1256 for (const PasswordForm* password_form : possible_submitted_forms) { |
| 1223 if (password_form && !password_form->username_value.empty() && | 1257 if (password_form && !password_form->username_value.empty() && |
| 1224 FormContainsNonDefaultPasswordValue(*password_form)) { | 1258 FormContainsNonDefaultPasswordValue(*password_form)) { |
| 1225 password_forms_found = true; | 1259 password_forms_found = true; |
| 1226 if (logger) { | 1260 if (logger) { |
| 1227 logger->LogPasswordForm(Logger::STRING_PASSWORD_FORM_FOUND_ON_PAGE, | 1261 logger->LogPasswordForm(Logger::STRING_PASSWORD_FORM_FOUND_ON_PAGE, |
| 1228 *password_form); | 1262 *password_form); |
| 1229 } | 1263 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1261 | 1295 |
| 1262 for (auto element : elements) { | 1296 for (auto element : elements) { |
| 1263 blink::WebInputElement username_element = | 1297 blink::WebInputElement username_element = |
| 1264 !element.isPasswordField() ? element : password_to_username_[element]; | 1298 !element.isPasswordField() ? element : password_to_username_[element]; |
| 1265 blink::WebInputElement password_element = | 1299 blink::WebInputElement password_element = |
| 1266 element.isPasswordField() | 1300 element.isPasswordField() |
| 1267 ? element | 1301 ? element |
| 1268 : web_input_to_password_info_[element].password_field; | 1302 : web_input_to_password_info_[element].password_field; |
| 1269 FillFormOnPasswordReceived( | 1303 FillFormOnPasswordReceived( |
| 1270 form_data, username_element, password_element, | 1304 form_data, username_element, password_element, |
| 1271 &nonscript_modified_values_, | 1305 &field_value_and_properties_map_, |
| 1272 base::Bind(&PasswordValueGatekeeper::RegisterElement, | 1306 base::Bind(&PasswordValueGatekeeper::RegisterElement, |
| 1273 base::Unretained(&gatekeeper_)), | 1307 base::Unretained(&gatekeeper_)), |
| 1274 logger.get()); | 1308 logger.get()); |
| 1275 } | 1309 } |
| 1276 } | 1310 } |
| 1277 | 1311 |
| 1278 void PasswordAutofillAgent::GetFillableElementFromFormData( | 1312 void PasswordAutofillAgent::GetFillableElementFromFormData( |
| 1279 int key, | 1313 int key, |
| 1280 const PasswordFormFillData& form_data, | 1314 const PasswordFormFillData& form_data, |
| 1281 RendererSavePasswordProgressLogger* logger, | 1315 RendererSavePasswordProgressLogger* logger, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1349 password_info.key = key; | 1383 password_info.key = key; |
| 1350 password_info.password_field = password_element; | 1384 password_info.password_field = password_element; |
| 1351 web_input_to_password_info_[main_element] = password_info; | 1385 web_input_to_password_info_[main_element] = password_info; |
| 1352 if (!main_element.isPasswordField()) | 1386 if (!main_element.isPasswordField()) |
| 1353 password_to_username_[password_element] = username_element; | 1387 password_to_username_[password_element] = username_element; |
| 1354 if (elements) | 1388 if (elements) |
| 1355 elements->push_back(main_element); | 1389 elements->push_back(main_element); |
| 1356 } | 1390 } |
| 1357 } | 1391 } |
| 1358 | 1392 |
| 1393 void PasswordAutofillAgent::FocusedNodeHasChanged(const blink::WebNode& node) { |
| 1394 if (node.isNull() || !node.isElementNode()) |
| 1395 return; |
| 1396 const blink::WebElement web_element = node.toConst<blink::WebElement>(); |
| 1397 if (!web_element.isFormControlElement()) |
| 1398 return; |
| 1399 const blink::WebFormControlElement control_element = |
| 1400 web_element.toConst<blink::WebFormControlElement>(); |
| 1401 UpdateFieldValueAndPropertiesMaskMap(control_element, nullptr, |
| 1402 FieldPropertiesFlags::HAD_FOCUS, |
| 1403 &field_value_and_properties_map_); |
| 1404 } |
| 1405 |
| 1359 void PasswordAutofillAgent::OnSetLoggingState(bool active) { | 1406 void PasswordAutofillAgent::OnSetLoggingState(bool active) { |
| 1360 logging_state_active_ = active; | 1407 logging_state_active_ = active; |
| 1361 } | 1408 } |
| 1362 | 1409 |
| 1363 void PasswordAutofillAgent::OnAutofillUsernameAndPasswordDataReceived( | 1410 void PasswordAutofillAgent::OnAutofillUsernameAndPasswordDataReceived( |
| 1364 const FormsPredictionsMap& predictions) { | 1411 const FormsPredictionsMap& predictions) { |
| 1365 form_predictions_.insert(predictions.begin(), predictions.end()); | 1412 form_predictions_.insert(predictions.begin(), predictions.end()); |
| 1366 } | 1413 } |
| 1367 | 1414 |
| 1368 void PasswordAutofillAgent::OnFindFocusedPasswordForm() { | 1415 void PasswordAutofillAgent::OnFindFocusedPasswordForm() { |
| 1369 std::unique_ptr<PasswordForm> password_form; | 1416 std::unique_ptr<PasswordForm> password_form; |
| 1370 | 1417 |
| 1371 blink::WebElement element = | 1418 blink::WebElement element = |
| 1372 render_frame()->GetWebFrame()->document().focusedElement(); | 1419 render_frame()->GetWebFrame()->document().focusedElement(); |
| 1373 if (!element.isNull() && element.hasHTMLTagName("input")) { | 1420 if (!element.isNull() && element.hasHTMLTagName("input")) { |
| 1374 blink::WebInputElement input = element.to<blink::WebInputElement>(); | 1421 blink::WebInputElement input = element.to<blink::WebInputElement>(); |
| 1375 if (input.isPasswordField() && !input.form().isNull()) { | 1422 if (input.isPasswordField() && !input.form().isNull()) { |
| 1376 if (!input.form().isNull()) { | 1423 if (!input.form().isNull()) { |
| 1377 password_form = CreatePasswordFormFromWebForm( | 1424 password_form = CreatePasswordFormFromWebForm( |
| 1378 input.form(), &nonscript_modified_values_, &form_predictions_); | 1425 input.form(), &field_value_and_properties_map_, &form_predictions_); |
| 1379 } else { | 1426 } else { |
| 1380 password_form = CreatePasswordFormFromUnownedInputElements( | 1427 password_form = CreatePasswordFormFromUnownedInputElements( |
| 1381 *render_frame()->GetWebFrame(), | 1428 *render_frame()->GetWebFrame(), &field_value_and_properties_map_, |
| 1382 &nonscript_modified_values_, &form_predictions_); | 1429 &form_predictions_); |
| 1383 // Only try to use this form if |input| is one of the password elements | 1430 // Only try to use this form if |input| is one of the password elements |
| 1384 // for |password_form|. | 1431 // for |password_form|. |
| 1385 if (password_form->password_element != input.nameForAutofill() && | 1432 if (password_form->password_element != input.nameForAutofill() && |
| 1386 password_form->new_password_element != input.nameForAutofill()) | 1433 password_form->new_password_element != input.nameForAutofill()) |
| 1387 password_form.reset(); | 1434 password_form.reset(); |
| 1388 } | 1435 } |
| 1389 } | 1436 } |
| 1390 } | 1437 } |
| 1391 | 1438 |
| 1392 if (!password_form) | 1439 if (!password_form) |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1441 username_query_prefix_ = username_string; | 1488 username_query_prefix_ = username_string; |
| 1442 return CanShowSuggestion(password_info.fill_data, username_string, show_all); | 1489 return CanShowSuggestion(password_info.fill_data, username_string, show_all); |
| 1443 } | 1490 } |
| 1444 | 1491 |
| 1445 void PasswordAutofillAgent::FrameClosing() { | 1492 void PasswordAutofillAgent::FrameClosing() { |
| 1446 for (auto const& iter : web_input_to_password_info_) { | 1493 for (auto const& iter : web_input_to_password_info_) { |
| 1447 password_to_username_.erase(iter.second.password_field); | 1494 password_to_username_.erase(iter.second.password_field); |
| 1448 } | 1495 } |
| 1449 web_input_to_password_info_.clear(); | 1496 web_input_to_password_info_.clear(); |
| 1450 provisionally_saved_form_.reset(); | 1497 provisionally_saved_form_.reset(); |
| 1451 nonscript_modified_values_.clear(); | 1498 field_value_and_properties_map_.clear(); |
| 1452 } | 1499 } |
| 1453 | 1500 |
| 1454 void PasswordAutofillAgent::ClearPreview( | 1501 void PasswordAutofillAgent::ClearPreview( |
| 1455 blink::WebInputElement* username, | 1502 blink::WebInputElement* username, |
| 1456 blink::WebInputElement* password) { | 1503 blink::WebInputElement* password) { |
| 1457 if (!username->isNull() && !username->suggestedValue().isEmpty()) { | 1504 if (!username->isNull() && !username->suggestedValue().isEmpty()) { |
| 1458 username->setSuggestedValue(blink::WebString()); | 1505 username->setSuggestedValue(blink::WebString()); |
| 1459 username->setAutofilled(was_username_autofilled_); | 1506 username->setAutofilled(was_username_autofilled_); |
| 1460 username->setSelectionRange(username_query_prefix_.length(), | 1507 username->setSelectionRange(username_query_prefix_.length(), |
| 1461 username->value().length()); | 1508 username->value().length()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1483 !(provisionally_saved_form_->password_value.empty() && | 1530 !(provisionally_saved_form_->password_value.empty() && |
| 1484 provisionally_saved_form_->new_password_value.empty()); | 1531 provisionally_saved_form_->new_password_value.empty()); |
| 1485 } | 1532 } |
| 1486 | 1533 |
| 1487 const mojom::AutofillDriverPtr& PasswordAutofillAgent::GetAutofillDriver() { | 1534 const mojom::AutofillDriverPtr& PasswordAutofillAgent::GetAutofillDriver() { |
| 1488 DCHECK(autofill_agent_); | 1535 DCHECK(autofill_agent_); |
| 1489 return autofill_agent_->GetAutofillDriver(); | 1536 return autofill_agent_->GetAutofillDriver(); |
| 1490 } | 1537 } |
| 1491 | 1538 |
| 1492 } // namespace autofill | 1539 } // namespace autofill |
| OLD | NEW |