| 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> |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 160 bool found_input = false; | 160 bool found_input = false; |
| 161 bool is_password_field = IsPasswordField(field); | 161 bool is_password_field = IsPasswordField(field); |
| 162 bool does_password_field_has_ambigous_or_empty_name = | 162 bool does_password_field_has_ambigous_or_empty_name = |
| 163 ambiguous_or_empty_names && is_password_field; | 163 ambiguous_or_empty_names && is_password_field; |
| 164 bool ambiguous_and_multiple_password_fields_with_autocomplete = | 164 bool ambiguous_and_multiple_password_fields_with_autocomplete = |
| 165 does_password_field_has_ambigous_or_empty_name && | 165 does_password_field_has_ambigous_or_empty_name && |
| 166 HasPasswordWithAutocompleteAttribute(control_elements); | 166 HasPasswordWithAutocompleteAttribute(control_elements); |
| 167 base::string16 field_name = FieldName(field, ambiguous_or_empty_names); | 167 base::string16 field_name = FieldName(field, ambiguous_or_empty_names); |
| 168 for (const blink::WebFormControlElement& control_element : control_elements) { | 168 for (const blink::WebFormControlElement& control_element : control_elements) { |
| 169 if (!ambiguous_or_empty_names && | 169 if (!ambiguous_or_empty_names && |
| 170 control_element.nameForAutofill() != field_name) { | 170 control_element.nameForAutofill().utf16() != field_name) { |
| 171 continue; | 171 continue; |
| 172 } | 172 } |
| 173 | 173 |
| 174 if (!control_element.hasHTMLTagName("input")) | 174 if (!control_element.hasHTMLTagName("input")) |
| 175 continue; | 175 continue; |
| 176 | 176 |
| 177 // Only fill saved passwords into password fields and usernames into text | 177 // Only fill saved passwords into password fields and usernames into text |
| 178 // fields. | 178 // fields. |
| 179 const blink::WebInputElement input_element = | 179 const blink::WebInputElement input_element = |
| 180 control_element.toConst<blink::WebInputElement>(); | 180 control_element.toConst<blink::WebInputElement>(); |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 RendererSavePasswordProgressLogger* logger) { | 392 RendererSavePasswordProgressLogger* logger) { |
| 393 if (logger) | 393 if (logger) |
| 394 logger->LogMessage(Logger::STRING_FILL_USERNAME_AND_PASSWORD_METHOD); | 394 logger->LogMessage(Logger::STRING_FILL_USERNAME_AND_PASSWORD_METHOD); |
| 395 | 395 |
| 396 // Don't fill username if password can't be set. | 396 // Don't fill username if password can't be set. |
| 397 if (!IsElementAutocompletable(*password_element)) | 397 if (!IsElementAutocompletable(*password_element)) |
| 398 return false; | 398 return false; |
| 399 | 399 |
| 400 base::string16 current_username; | 400 base::string16 current_username; |
| 401 if (!username_element->isNull()) { | 401 if (!username_element->isNull()) { |
| 402 current_username = username_element->value(); | 402 current_username = username_element->value().utf16(); |
| 403 } | 403 } |
| 404 | 404 |
| 405 // username and password will contain the match found if any. | 405 // username and password will contain the match found if any. |
| 406 base::string16 username; | 406 base::string16 username; |
| 407 base::string16 password; | 407 base::string16 password; |
| 408 | 408 |
| 409 // Look for any suitable matches to current field text. | 409 // Look for any suitable matches to current field text. |
| 410 if (DoUsernamesMatch(fill_data.username_field.value, current_username, | 410 if (DoUsernamesMatch(fill_data.username_field.value, current_username, |
| 411 exact_username_match)) { | 411 exact_username_match)) { |
| 412 username = fill_data.username_field.value; | 412 username = fill_data.username_field.value; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 446 if (password.empty()) | 446 if (password.empty()) |
| 447 return false; | 447 return false; |
| 448 | 448 |
| 449 // TODO(tkent): Check maxlength and pattern for both username and password | 449 // TODO(tkent): Check maxlength and pattern for both username and password |
| 450 // fields. | 450 // fields. |
| 451 | 451 |
| 452 // Input matches the username, fill in required values. | 452 // Input matches the username, fill in required values. |
| 453 if (!username_element->isNull() && | 453 if (!username_element->isNull() && |
| 454 IsElementAutocompletable(*username_element)) { | 454 IsElementAutocompletable(*username_element)) { |
| 455 // TODO(crbug.com/507714): Why not setSuggestedValue? | 455 // TODO(crbug.com/507714): Why not setSuggestedValue? |
| 456 username_element->setValue(username, true); | 456 username_element->setValue(blink::WebString::fromUTF16(username), true); |
| 457 UpdateFieldValueAndPropertiesMaskMap(*username_element, &username, | 457 UpdateFieldValueAndPropertiesMaskMap(*username_element, &username, |
| 458 FieldPropertiesFlags::AUTOFILLED, | 458 FieldPropertiesFlags::AUTOFILLED, |
| 459 field_value_and_properties_map); | 459 field_value_and_properties_map); |
| 460 username_element->setAutofilled(true); | 460 username_element->setAutofilled(true); |
| 461 if (logger) | 461 if (logger) |
| 462 logger->LogElementName(Logger::STRING_USERNAME_FILLED, *username_element); | 462 logger->LogElementName(Logger::STRING_USERNAME_FILLED, *username_element); |
| 463 if (set_selection) { | 463 if (set_selection) { |
| 464 form_util::PreviewSuggestion(username, current_username, | 464 form_util::PreviewSuggestion(username, current_username, |
| 465 username_element); | 465 username_element); |
| 466 } | 466 } |
| 467 } else if (current_username != username) { | 467 } else if (current_username != username) { |
| 468 // If the username can't be filled and it doesn't match a saved password | 468 // If the username can't be filled and it doesn't match a saved password |
| 469 // as is, don't autofill a password. | 469 // as is, don't autofill a password. |
| 470 return false; | 470 return false; |
| 471 } | 471 } |
| 472 | 472 |
| 473 // Wait to fill in the password until a user gesture occurs. This is to make | 473 // Wait to fill in the password until a user gesture occurs. This is to make |
| 474 // sure that we do not fill in the DOM with a password until we believe the | 474 // sure that we do not fill in the DOM with a password until we believe the |
| 475 // user is intentionally interacting with the page. | 475 // user is intentionally interacting with the page. |
| 476 password_element->setSuggestedValue(password); | 476 password_element->setSuggestedValue(blink::WebString::fromUTF16(password)); |
| 477 UpdateFieldValueAndPropertiesMaskMap(*password_element, &password, | 477 UpdateFieldValueAndPropertiesMaskMap(*password_element, &password, |
| 478 FieldPropertiesFlags::AUTOFILLED, | 478 FieldPropertiesFlags::AUTOFILLED, |
| 479 field_value_and_properties_map); | 479 field_value_and_properties_map); |
| 480 registration_callback.Run(password_element); | 480 registration_callback.Run(password_element); |
| 481 | 481 |
| 482 password_element->setAutofilled(true); | 482 password_element->setAutofilled(true); |
| 483 if (logger) | 483 if (logger) |
| 484 logger->LogElementName(Logger::STRING_PASSWORD_FILLED, *password_element); | 484 logger->LogElementName(Logger::STRING_PASSWORD_FILLED, *password_element); |
| 485 return true; | 485 return true; |
| 486 } | 486 } |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 541 // select to fill the password element, so the password element must be marked | 541 // select to fill the password element, so the password element must be marked |
| 542 // as autofilled and the fill step should also be skipped if the user is not | 542 // as autofilled and the fill step should also be skipped if the user is not |
| 543 // in the "no highlighting" group. | 543 // in the "no highlighting" group. |
| 544 // | 544 // |
| 545 // In all other cases, do nothing. | 545 // In all other cases, do nothing. |
| 546 bool form_has_fillable_username = !username_field_name.empty() && | 546 bool form_has_fillable_username = !username_field_name.empty() && |
| 547 IsElementAutocompletable(username_element); | 547 IsElementAutocompletable(username_element); |
| 548 | 548 |
| 549 if (form_has_fillable_username && username_element.value().isEmpty()) { | 549 if (form_has_fillable_username && username_element.value().isEmpty()) { |
| 550 // TODO(tkent): Check maxlength and pattern. | 550 // TODO(tkent): Check maxlength and pattern. |
| 551 username_element.setValue(fill_data.username_field.value, true); | 551 username_element.setValue( |
| 552 blink::WebString::fromUTF16(fill_data.username_field.value), true); |
| 552 } | 553 } |
| 553 | 554 |
| 554 // Fill if we have an exact match for the username. Note that this sets | 555 // Fill if we have an exact match for the username. Note that this sets |
| 555 // username to autofilled. | 556 // username to autofilled. |
| 556 return FillUserNameAndPassword( | 557 return FillUserNameAndPassword( |
| 557 &username_element, &password_element, fill_data, | 558 &username_element, &password_element, fill_data, |
| 558 true /* exact_username_match */, false /* set_selection */, | 559 true /* exact_username_match */, false /* set_selection */, |
| 559 field_value_and_properties_map, registration_callback, logger); | 560 field_value_and_properties_map, registration_callback, logger); |
| 560 } | 561 } |
| 561 | 562 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 // Show the popup with the list of available usernames. | 639 // Show the popup with the list of available usernames. |
| 639 return ShowSuggestions(element, false, false); | 640 return ShowSuggestions(element, false, false); |
| 640 } | 641 } |
| 641 | 642 |
| 642 void PasswordAutofillAgent::UpdateStateForTextChange( | 643 void PasswordAutofillAgent::UpdateStateForTextChange( |
| 643 const blink::WebInputElement& element) { | 644 const blink::WebInputElement& element) { |
| 644 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 | 645 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 |
| 645 blink::WebInputElement mutable_element = element; // We need a non-const. | 646 blink::WebInputElement mutable_element = element; // We need a non-const. |
| 646 | 647 |
| 647 if (element.isTextField()) { | 648 if (element.isTextField()) { |
| 648 const base::string16 element_value = element.value(); | 649 const base::string16 element_value = element.value().utf16(); |
| 649 UpdateFieldValueAndPropertiesMaskMap(element, &element_value, | 650 UpdateFieldValueAndPropertiesMaskMap(element, &element_value, |
| 650 FieldPropertiesFlags::USER_TYPED, | 651 FieldPropertiesFlags::USER_TYPED, |
| 651 &field_value_and_properties_map_); | 652 &field_value_and_properties_map_); |
| 652 } | 653 } |
| 653 | 654 |
| 654 blink::WebFrame* const element_frame = element.document().frame(); | 655 blink::WebFrame* const element_frame = element.document().frame(); |
| 655 // The element's frame might have been detached in the meantime (see | 656 // The element's frame might have been detached in the meantime (see |
| 656 // http://crbug.com/585363, comments 5 and 6), in which case frame() will | 657 // http://crbug.com/585363, comments 5 and 6), in which case frame() will |
| 657 // return null. This was hardly caused by form submission (unless the user | 658 // return null. This was hardly caused by form submission (unless the user |
| 658 // is supernaturally quick), so it is OK to drop the ball here. | 659 // is supernaturally quick), so it is OK to drop the ball here. |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 !IsElementAutocompletable(password_element)) { | 706 !IsElementAutocompletable(password_element)) { |
| 706 return false; | 707 return false; |
| 707 } | 708 } |
| 708 | 709 |
| 709 password_info->password_was_edited_last = false; | 710 password_info->password_was_edited_last = false; |
| 710 if (element->isPasswordField()) { | 711 if (element->isPasswordField()) { |
| 711 password_info->password_field_suggestion_was_accepted = true; | 712 password_info->password_field_suggestion_was_accepted = true; |
| 712 password_info->password_field = password_element; | 713 password_info->password_field = password_element; |
| 713 } else if (!username_element.isNull() && | 714 } else if (!username_element.isNull() && |
| 714 IsElementAutocompletable(username_element)) { | 715 IsElementAutocompletable(username_element)) { |
| 715 username_element.setValue(blink::WebString(username), true); | 716 username_element.setValue(blink::WebString::fromUTF16(username), true); |
| 716 username_element.setAutofilled(true); | 717 username_element.setAutofilled(true); |
| 717 UpdateFieldValueAndPropertiesMaskMap(username_element, &username, | 718 UpdateFieldValueAndPropertiesMaskMap(username_element, &username, |
| 718 FieldPropertiesFlags::AUTOFILLED, | 719 FieldPropertiesFlags::AUTOFILLED, |
| 719 &field_value_and_properties_map_); | 720 &field_value_and_properties_map_); |
| 720 } | 721 } |
| 721 | 722 |
| 722 password_element.setValue(blink::WebString(password), true); | 723 password_element.setValue(blink::WebString::fromUTF16(password), true); |
| 723 password_element.setAutofilled(true); | 724 password_element.setAutofilled(true); |
| 724 UpdateFieldValueAndPropertiesMaskMap(password_element, &password, | 725 UpdateFieldValueAndPropertiesMaskMap(password_element, &password, |
| 725 FieldPropertiesFlags::AUTOFILLED, | 726 FieldPropertiesFlags::AUTOFILLED, |
| 726 &field_value_and_properties_map_); | 727 &field_value_and_properties_map_); |
| 727 | 728 |
| 728 blink::WebInputElement mutable_filled_element = *element; | 729 blink::WebInputElement mutable_filled_element = *element; |
| 729 mutable_filled_element.setSelectionRange(element->value().length(), | 730 mutable_filled_element.setSelectionRange(element->value().length(), |
| 730 element->value().length()); | 731 element->value().length()); |
| 731 | 732 |
| 732 return true; | 733 return true; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 747 | 748 |
| 748 if (!FindPasswordInfoForElement(*element, &username_element, | 749 if (!FindPasswordInfoForElement(*element, &username_element, |
| 749 &password_element, &password_info) || | 750 &password_element, &password_info) || |
| 750 !IsElementAutocompletable(password_element)) { | 751 !IsElementAutocompletable(password_element)) { |
| 751 return false; | 752 return false; |
| 752 } | 753 } |
| 753 | 754 |
| 754 if (!element->isPasswordField() && !username_element.isNull() && | 755 if (!element->isPasswordField() && !username_element.isNull() && |
| 755 IsElementAutocompletable(username_element)) { | 756 IsElementAutocompletable(username_element)) { |
| 756 if (username_query_prefix_.empty()) | 757 if (username_query_prefix_.empty()) |
| 757 username_query_prefix_ = username_element.value(); | 758 username_query_prefix_ = username_element.value().utf16(); |
| 758 | 759 |
| 759 was_username_autofilled_ = username_element.isAutofilled(); | 760 was_username_autofilled_ = username_element.isAutofilled(); |
| 760 username_element.setSuggestedValue(username); | 761 username_element.setSuggestedValue(username); |
| 761 username_element.setAutofilled(true); | 762 username_element.setAutofilled(true); |
| 762 form_util::PreviewSuggestion(username_element.suggestedValue(), | 763 form_util::PreviewSuggestion(username_element.suggestedValue().utf16(), |
| 763 username_query_prefix_, &username_element); | 764 username_query_prefix_, &username_element); |
| 764 } | 765 } |
| 765 was_password_autofilled_ = password_element.isAutofilled(); | 766 was_password_autofilled_ = password_element.isAutofilled(); |
| 766 password_element.setSuggestedValue(password); | 767 password_element.setSuggestedValue(password); |
| 767 password_element.setAutofilled(true); | 768 password_element.setAutofilled(true); |
| 768 | 769 |
| 769 return true; | 770 return true; |
| 770 } | 771 } |
| 771 | 772 |
| 772 bool PasswordAutofillAgent::DidClearAutofillSelection( | 773 bool PasswordAutofillAgent::DidClearAutofillSelection( |
| (...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1386 if (input.isPasswordField() && !input.form().isNull()) { | 1387 if (input.isPasswordField() && !input.form().isNull()) { |
| 1387 if (!input.form().isNull()) { | 1388 if (!input.form().isNull()) { |
| 1388 password_form = CreatePasswordFormFromWebForm( | 1389 password_form = CreatePasswordFormFromWebForm( |
| 1389 input.form(), &field_value_and_properties_map_, &form_predictions_); | 1390 input.form(), &field_value_and_properties_map_, &form_predictions_); |
| 1390 } else { | 1391 } else { |
| 1391 password_form = CreatePasswordFormFromUnownedInputElements( | 1392 password_form = CreatePasswordFormFromUnownedInputElements( |
| 1392 *render_frame()->GetWebFrame(), &field_value_and_properties_map_, | 1393 *render_frame()->GetWebFrame(), &field_value_and_properties_map_, |
| 1393 &form_predictions_); | 1394 &form_predictions_); |
| 1394 // Only try to use this form if |input| is one of the password elements | 1395 // Only try to use this form if |input| is one of the password elements |
| 1395 // for |password_form|. | 1396 // for |password_form|. |
| 1396 if (password_form->password_element != input.nameForAutofill() && | 1397 if (password_form->password_element != |
| 1397 password_form->new_password_element != input.nameForAutofill()) | 1398 input.nameForAutofill().utf16() && |
| 1399 password_form->new_password_element != |
| 1400 input.nameForAutofill().utf16()) |
| 1398 password_form.reset(); | 1401 password_form.reset(); |
| 1399 } | 1402 } |
| 1400 } | 1403 } |
| 1401 } | 1404 } |
| 1402 | 1405 |
| 1403 if (!password_form) | 1406 if (!password_form) |
| 1404 password_form.reset(new PasswordForm()); | 1407 password_form.reset(new PasswordForm()); |
| 1405 | 1408 |
| 1406 callback.Run(*password_form); | 1409 callback.Run(*password_form); |
| 1407 } | 1410 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1432 FormData form; | 1435 FormData form; |
| 1433 FormFieldData field; | 1436 FormFieldData field; |
| 1434 form_util::FindFormAndFieldForFormControlElement(user_input, &form, &field); | 1437 form_util::FindFormAndFieldForFormControlElement(user_input, &form, &field); |
| 1435 | 1438 |
| 1436 int options = 0; | 1439 int options = 0; |
| 1437 if (show_all) | 1440 if (show_all) |
| 1438 options |= SHOW_ALL; | 1441 options |= SHOW_ALL; |
| 1439 if (show_on_password_field) | 1442 if (show_on_password_field) |
| 1440 options |= IS_PASSWORD_FIELD; | 1443 options |= IS_PASSWORD_FIELD; |
| 1441 | 1444 |
| 1442 base::string16 username_string( | 1445 base::string16 username_string(user_input.isPasswordField() |
| 1443 user_input.isPasswordField() | 1446 ? base::string16() |
| 1444 ? base::string16() | 1447 : user_input.value().utf16()); |
| 1445 : static_cast<base::string16>(user_input.value())); | |
| 1446 | 1448 |
| 1447 GetPasswordManagerDriver()->ShowPasswordSuggestions( | 1449 GetPasswordManagerDriver()->ShowPasswordSuggestions( |
| 1448 password_info.key, field.text_direction, username_string, options, | 1450 password_info.key, field.text_direction, username_string, options, |
| 1449 render_frame()->GetRenderView()->ElementBoundsInWindow(user_input)); | 1451 render_frame()->GetRenderView()->ElementBoundsInWindow(user_input)); |
| 1450 username_query_prefix_ = username_string; | 1452 username_query_prefix_ = username_string; |
| 1451 return CanShowSuggestion(password_info.fill_data, username_string, show_all); | 1453 return CanShowSuggestion(password_info.fill_data, username_string, show_all); |
| 1452 } | 1454 } |
| 1453 | 1455 |
| 1454 void PasswordAutofillAgent::FrameClosing() { | 1456 void PasswordAutofillAgent::FrameClosing() { |
| 1455 for (auto const& iter : web_input_to_password_info_) { | 1457 for (auto const& iter : web_input_to_password_info_) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1502 PasswordAutofillAgent::GetPasswordManagerDriver() { | 1504 PasswordAutofillAgent::GetPasswordManagerDriver() { |
| 1503 if (!password_manager_driver_) { | 1505 if (!password_manager_driver_) { |
| 1504 render_frame()->GetRemoteInterfaces()->GetInterface( | 1506 render_frame()->GetRemoteInterfaces()->GetInterface( |
| 1505 mojo::MakeRequest(&password_manager_driver_)); | 1507 mojo::MakeRequest(&password_manager_driver_)); |
| 1506 } | 1508 } |
| 1507 | 1509 |
| 1508 return password_manager_driver_; | 1510 return password_manager_driver_; |
| 1509 } | 1511 } |
| 1510 | 1512 |
| 1511 } // namespace autofill | 1513 } // namespace autofill |
| OLD | NEW |