| 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 <utility> | 10 #include <utility> |
| (...skipping 711 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 722 } | 722 } |
| 723 | 723 |
| 724 void PasswordAutofillAgent::UpdateStateForTextChange( | 724 void PasswordAutofillAgent::UpdateStateForTextChange( |
| 725 const blink::WebInputElement& element) { | 725 const blink::WebInputElement& element) { |
| 726 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 | 726 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 |
| 727 blink::WebInputElement mutable_element = element; // We need a non-const. | 727 blink::WebInputElement mutable_element = element; // We need a non-const. |
| 728 | 728 |
| 729 if (element.isTextField()) | 729 if (element.isTextField()) |
| 730 nonscript_modified_values_[element] = element.value(); | 730 nonscript_modified_values_[element] = element.value(); |
| 731 | 731 |
| 732 WebInputToPasswordInfoMap::iterator password_info_iter = | |
| 733 web_input_to_password_info_.find(element); | |
| 734 if (password_info_iter != web_input_to_password_info_.end()) { | |
| 735 password_info_iter->second.username_was_edited = true; | |
| 736 } | |
| 737 | |
| 738 blink::WebFrame* const element_frame = element.document().frame(); | 732 blink::WebFrame* const element_frame = element.document().frame(); |
| 739 // The element's frame might have been detached in the meantime (see | 733 // The element's frame might have been detached in the meantime (see |
| 740 // http://crbug.com/585363, comments 5 and 6), in which case frame() will | 734 // http://crbug.com/585363, comments 5 and 6), in which case frame() will |
| 741 // return null. This was hardly caused by form submission (unless the user | 735 // return null. This was hardly caused by form submission (unless the user |
| 742 // is supernaturally quick), so it is OK to drop the ball here. | 736 // is supernaturally quick), so it is OK to drop the ball here. |
| 743 if (!element_frame) | 737 if (!element_frame) |
| 744 return; | 738 return; |
| 745 DCHECK_EQ(element_frame, render_frame()->GetWebFrame()); | 739 DCHECK_EQ(element_frame, render_frame()->GetWebFrame()); |
| 746 | 740 |
| 747 // Some login forms have event handlers that put a hash of the password into | 741 // Some login forms have event handlers that put a hash of the password into |
| (...skipping 17 matching lines...) Expand all Loading... |
| 765 if (iter != password_to_username_.end()) { | 759 if (iter != password_to_username_.end()) { |
| 766 web_input_to_password_info_[iter->second].password_was_edited_last = true; | 760 web_input_to_password_info_[iter->second].password_was_edited_last = true; |
| 767 // Note that the suggested value of |mutable_element| was reset when its | 761 // Note that the suggested value of |mutable_element| was reset when its |
| 768 // value changed. | 762 // value changed. |
| 769 mutable_element.setAutofilled(false); | 763 mutable_element.setAutofilled(false); |
| 770 } | 764 } |
| 771 } | 765 } |
| 772 } | 766 } |
| 773 | 767 |
| 774 bool PasswordAutofillAgent::FillSuggestion( | 768 bool PasswordAutofillAgent::FillSuggestion( |
| 775 const blink::WebNode& node, | 769 const blink::WebFormControlElement& control_element, |
| 776 const blink::WebString& username, | 770 const blink::WebString& username, |
| 777 const blink::WebString& password) { | 771 const blink::WebString& password) { |
| 778 // The element in context of the suggestion popup. | 772 // The element in context of the suggestion popup. |
| 779 blink::WebInputElement filled_element; | 773 const blink::WebInputElement* element = toWebInputElement(&control_element); |
| 774 if (!element) |
| 775 return false; |
| 776 |
| 777 blink::WebInputElement username_element; |
| 778 blink::WebInputElement password_element; |
| 780 PasswordInfo* password_info; | 779 PasswordInfo* password_info; |
| 781 | 780 |
| 782 if (!FindLoginInfo(node, &filled_element, &password_info) || | 781 if (!FindPasswordInfoForElement(*element, &username_element, |
| 783 !IsElementAutocompletable(filled_element) || | 782 &password_element, &password_info) || |
| 784 !IsElementAutocompletable(password_info->password_field)) { | 783 (!username_element.isNull() && |
| 784 !IsElementAutocompletable(username_element)) || |
| 785 !IsElementAutocompletable(password_element)) { |
| 785 return false; | 786 return false; |
| 786 } | 787 } |
| 787 | 788 |
| 788 password_info->password_was_edited_last = false; | 789 password_info->password_was_edited_last = false; |
| 789 // Note that in cases where filled_element is the password element, the value | 790 if (element->isPasswordField()) { |
| 790 // gets overwritten with the correct one below. | 791 password_info->password_field_suggestion_was_accepted = true; |
| 791 filled_element.setValue(username, true); | 792 password_info->password_field = password_element; |
| 792 filled_element.setAutofilled(true); | 793 } else if (!username_element.isNull()) { |
| 793 nonscript_modified_values_[filled_element] = username; | 794 username_element.setValue(username, true); |
| 795 username_element.setAutofilled(true); |
| 796 nonscript_modified_values_[username_element] = username; |
| 797 } |
| 794 | 798 |
| 795 password_info->password_field.setValue(password, true); | 799 password_element.setValue(password, true); |
| 796 password_info->password_field.setAutofilled(true); | 800 password_element.setAutofilled(true); |
| 797 nonscript_modified_values_[password_info->password_field] = password; | 801 nonscript_modified_values_[password_element] = password; |
| 798 | 802 |
| 799 filled_element.setSelectionRange(filled_element.value().length(), | 803 blink::WebInputElement mutable_filled_element = *element; |
| 800 filled_element.value().length()); | 804 mutable_filled_element.setSelectionRange(element->value().length(), |
| 805 element->value().length()); |
| 801 | 806 |
| 802 return true; | 807 return true; |
| 803 } | 808 } |
| 804 | 809 |
| 805 bool PasswordAutofillAgent::PreviewSuggestion( | 810 bool PasswordAutofillAgent::PreviewSuggestion( |
| 806 const blink::WebNode& node, | 811 const blink::WebFormControlElement& control_element, |
| 807 const blink::WebString& username, | 812 const blink::WebString& username, |
| 808 const blink::WebString& password) { | 813 const blink::WebString& password) { |
| 814 // The element in context of the suggestion popup. |
| 815 const blink::WebInputElement* element = toWebInputElement(&control_element); |
| 816 if (!element) |
| 817 return false; |
| 818 |
| 809 blink::WebInputElement username_element; | 819 blink::WebInputElement username_element; |
| 820 blink::WebInputElement password_element; |
| 810 PasswordInfo* password_info; | 821 PasswordInfo* password_info; |
| 811 | 822 |
| 812 if (!FindLoginInfo(node, &username_element, &password_info) || | 823 if (!FindPasswordInfoForElement(*element, &username_element, |
| 813 !IsElementAutocompletable(username_element) || | 824 &password_element, &password_info) || |
| 814 !IsElementAutocompletable(password_info->password_field)) { | 825 (!username_element.isNull() && |
| 826 !IsElementAutocompletable(username_element)) || |
| 827 !IsElementAutocompletable(password_element)) { |
| 815 return false; | 828 return false; |
| 816 } | 829 } |
| 817 | 830 |
| 818 if (username_query_prefix_.empty()) | 831 if (!element->isPasswordField() && !username_element.isNull()) { |
| 819 username_query_prefix_ = username_element.value(); | 832 if (username_query_prefix_.empty()) |
| 833 username_query_prefix_ = username_element.value(); |
| 820 | 834 |
| 821 was_username_autofilled_ = username_element.isAutofilled(); | 835 was_username_autofilled_ = username_element.isAutofilled(); |
| 822 username_element.setSuggestedValue(username); | 836 username_element.setSuggestedValue(username); |
| 823 username_element.setAutofilled(true); | 837 username_element.setAutofilled(true); |
| 824 form_util::PreviewSuggestion(username_element.suggestedValue(), | 838 form_util::PreviewSuggestion(username_element.suggestedValue(), |
| 825 username_query_prefix_, &username_element); | 839 username_query_prefix_, &username_element); |
| 826 was_password_autofilled_ = password_info->password_field.isAutofilled(); | 840 } |
| 827 password_info->password_field.setSuggestedValue(password); | 841 was_password_autofilled_ = password_element.isAutofilled(); |
| 828 password_info->password_field.setAutofilled(true); | 842 password_element.setSuggestedValue(password); |
| 843 password_element.setAutofilled(true); |
| 829 | 844 |
| 830 return true; | 845 return true; |
| 831 } | 846 } |
| 832 | 847 |
| 833 bool PasswordAutofillAgent::DidClearAutofillSelection( | 848 bool PasswordAutofillAgent::DidClearAutofillSelection( |
| 834 const blink::WebNode& node) { | 849 const blink::WebFormControlElement& control_element) { |
| 835 blink::WebInputElement username_element; | 850 const blink::WebInputElement* element = toWebInputElement(&control_element); |
| 836 PasswordInfo* password_info; | 851 if (!element) |
| 837 if (!FindLoginInfo(node, &username_element, &password_info)) | |
| 838 return false; | 852 return false; |
| 839 | 853 |
| 840 ClearPreview(&username_element, &password_info->password_field); | 854 blink::WebInputElement username_element; |
| 855 blink::WebInputElement password_element; |
| 856 PasswordInfo* password_info; |
| 857 |
| 858 if (!FindPasswordInfoForElement(*element, &username_element, |
| 859 &password_element, &password_info)) |
| 860 return false; |
| 861 |
| 862 ClearPreview(&username_element, &password_element); |
| 841 return true; | 863 return true; |
| 842 } | 864 } |
| 843 | 865 |
| 844 bool PasswordAutofillAgent::FindPasswordInfoForElement( | 866 bool PasswordAutofillAgent::FindPasswordInfoForElement( |
| 845 const blink::WebInputElement& element, | 867 const blink::WebInputElement& element, |
| 846 const blink::WebInputElement** username_element, | 868 blink::WebInputElement* username_element, |
| 869 blink::WebInputElement* password_element, |
| 847 PasswordInfo** password_info) { | 870 PasswordInfo** password_info) { |
| 848 DCHECK(username_element && password_info); | 871 DCHECK(username_element && password_element && password_info); |
| 872 username_element->reset(); |
| 873 password_element->reset(); |
| 849 if (!element.isPasswordField()) { | 874 if (!element.isPasswordField()) { |
| 850 *username_element = &element; | 875 *username_element = element; |
| 851 } else { | 876 } else { |
| 852 WebInputToPasswordInfoMap::iterator iter = | 877 WebInputToPasswordInfoMap::iterator iter = |
| 853 web_input_to_password_info_.find(element); | 878 web_input_to_password_info_.find(element); |
| 854 if (iter != web_input_to_password_info_.end()) { | 879 if (iter != web_input_to_password_info_.end()) { |
| 855 // It's a password field without corresponding username field. | 880 // It's a password field without corresponding username field. |
| 856 *username_element = nullptr; | 881 *password_element = element; |
| 857 *password_info = &iter->second; | 882 *password_info = &iter->second; |
| 858 return true; | 883 return true; |
| 859 } | 884 } |
| 860 PasswordToLoginMap::const_iterator password_iter = | 885 PasswordToLoginMap::const_iterator password_iter = |
| 861 password_to_username_.find(element); | 886 password_to_username_.find(element); |
| 862 if (password_iter == password_to_username_.end()) | 887 if (password_iter == password_to_username_.end()) { |
| 863 return false; | 888 if (web_input_to_password_info_.empty()) |
| 864 *username_element = &password_iter->second; | 889 return false; |
| 890 |
| 891 *password_element = element; |
| 892 // Now all PasswordInfo items refer to the same set of credentials for |
| 893 // fill, so it is ok to take any of them. |
| 894 *password_info = &web_input_to_password_info_.begin()->second; |
| 895 return true; |
| 896 } |
| 897 *username_element = password_iter->second; |
| 898 *password_element = element; |
| 865 } | 899 } |
| 866 | 900 |
| 867 WebInputToPasswordInfoMap::iterator iter = | 901 WebInputToPasswordInfoMap::iterator iter = |
| 868 web_input_to_password_info_.find(**username_element); | 902 web_input_to_password_info_.find(*username_element); |
| 869 | 903 |
| 870 if (iter == web_input_to_password_info_.end()) | 904 if (iter == web_input_to_password_info_.end()) |
| 871 return false; | 905 return false; |
| 872 | 906 |
| 873 *password_info = &iter->second; | 907 *password_info = &iter->second; |
| 908 if (password_element->isNull()) |
| 909 *password_element = (*password_info)->password_field; |
| 910 |
| 874 return true; | 911 return true; |
| 875 } | 912 } |
| 876 | 913 |
| 877 bool PasswordAutofillAgent::ShowSuggestions( | 914 bool PasswordAutofillAgent::ShowSuggestions( |
| 878 const blink::WebInputElement& element, | 915 const blink::WebInputElement& element, |
| 879 bool show_all, | 916 bool show_all, |
| 880 bool generation_popup_showing) { | 917 bool generation_popup_showing) { |
| 881 const blink::WebInputElement* username_element; | 918 blink::WebInputElement username_element; |
| 919 blink::WebInputElement password_element; |
| 882 PasswordInfo* password_info; | 920 PasswordInfo* password_info; |
| 883 if (!FindPasswordInfoForElement(element, &username_element, &password_info)) | 921 if (!FindPasswordInfoForElement(element, &username_element, &password_element, |
| 922 &password_info)) |
| 884 return false; | 923 return false; |
| 885 | 924 |
| 886 // If autocomplete='off' is set on the form elements, no suggestion dialog | 925 // If autocomplete='off' is set on the form elements, no suggestion dialog |
| 887 // should be shown. However, return |true| to indicate that this is a known | 926 // should be shown. However, return |true| to indicate that this is a known |
| 888 // password form and that the request to show suggestions has been handled (as | 927 // password form and that the request to show suggestions has been handled (as |
| 889 // a no-op). | 928 // a no-op). |
| 890 if (!element.isTextField() || !IsElementAutocompletable(element) || | 929 if (!element.isTextField() || !IsElementAutocompletable(element) || |
| 891 !IsElementAutocompletable(password_info->password_field)) | 930 !IsElementAutocompletable(password_info->password_field)) |
| 892 return true; | 931 return true; |
| 893 | 932 |
| 894 if (element.nameForAutofill().isEmpty() && | 933 if (element.nameForAutofill().isEmpty() && |
| 895 !DoesFormContainAmbiguousOrEmptyNames(password_info->fill_data)) { | 934 !DoesFormContainAmbiguousOrEmptyNames(password_info->fill_data)) { |
| 896 return false; // If the field has no name, then we won't have values. | 935 return false; // If the field has no name, then we won't have values. |
| 897 } | 936 } |
| 898 | 937 |
| 899 // Don't attempt to autofill with values that are too large. | 938 // Don't attempt to autofill with values that are too large. |
| 900 if (element.value().length() > kMaximumTextSizeForAutocomplete) | 939 if (element.value().length() > kMaximumTextSizeForAutocomplete) |
| 901 return false; | 940 return false; |
| 902 | 941 |
| 903 bool username_is_available = username_element && | 942 // If the element is a password field, do not to show a popup if the user has |
| 904 !username_element->isNull() && | 943 // already accepted a password suggestion on another password field. |
| 905 IsElementEditable(*username_element); | 944 if (element.isPasswordField() && |
| 906 // If the element is a password field, a popup should only be shown if there | 945 (password_info->password_field_suggestion_was_accepted && |
| 907 // is no username or the corresponding username element is not editable since | 946 element != password_info->password_field)) |
| 908 // it is only in that case that the username element does not have a | |
| 909 // suggestions popup. | |
| 910 if (element.isPasswordField() && username_is_available && | |
| 911 (!password_info->fill_data.is_possible_change_password_form || | |
| 912 password_info->username_was_edited)) | |
| 913 return true; | 947 return true; |
| 914 | 948 |
| 915 UMA_HISTOGRAM_BOOLEAN( | 949 UMA_HISTOGRAM_BOOLEAN( |
| 916 "PasswordManager.AutocompletePopupSuppressedByGeneration", | 950 "PasswordManager.AutocompletePopupSuppressedByGeneration", |
| 917 generation_popup_showing); | 951 generation_popup_showing); |
| 918 | 952 |
| 919 if (generation_popup_showing) | 953 if (generation_popup_showing) |
| 920 return false; | 954 return false; |
| 921 | 955 |
| 922 // Chrome should never show more than one account for a password element since | 956 // Chrome should never show more than one account for a password element since |
| 923 // this implies that the username element cannot be modified. Thus even if | 957 // this implies that the username element cannot be modified. Thus even if |
| 924 // |show_all| is true, check if the element in question is a password element | 958 // |show_all| is true, check if the element in question is a password element |
| 925 // for the call to ShowSuggestionPopup. | 959 // for the call to ShowSuggestionPopup. |
| 926 return ShowSuggestionPopup( | 960 return ShowSuggestionPopup(*password_info, element, |
| 927 password_info->fill_data, | 961 show_all && !element.isPasswordField(), |
| 928 (!username_element || username_element->isNull()) ? element | 962 element.isPasswordField()); |
| 929 : *username_element, | |
| 930 show_all && !element.isPasswordField(), element.isPasswordField()); | |
| 931 } | 963 } |
| 932 | 964 |
| 933 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( | 965 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( |
| 934 const blink::WebSecurityOrigin& origin) { | 966 const blink::WebSecurityOrigin& origin) { |
| 935 return origin.canAccessPasswordManager(); | 967 return origin.canAccessPasswordManager(); |
| 936 } | 968 } |
| 937 | 969 |
| 938 void PasswordAutofillAgent::OnDynamicFormsSeen() { | 970 void PasswordAutofillAgent::OnDynamicFormsSeen() { |
| 939 SendPasswordForms(false /* only_visible */); | 971 SendPasswordForms(false /* only_visible */); |
| 940 } | 972 } |
| (...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1333 form_data, | 1365 form_data, |
| 1334 username_element, | 1366 username_element, |
| 1335 password_element, | 1367 password_element, |
| 1336 &nonscript_modified_values_, | 1368 &nonscript_modified_values_, |
| 1337 base::Bind(&PasswordValueGatekeeper::RegisterElement, | 1369 base::Bind(&PasswordValueGatekeeper::RegisterElement, |
| 1338 base::Unretained(&gatekeeper_))); | 1370 base::Unretained(&gatekeeper_))); |
| 1339 } | 1371 } |
| 1340 | 1372 |
| 1341 PasswordInfo password_info; | 1373 PasswordInfo password_info; |
| 1342 password_info.fill_data = form_data; | 1374 password_info.fill_data = form_data; |
| 1375 password_info.key = key; |
| 1343 password_info.password_field = password_element; | 1376 password_info.password_field = password_element; |
| 1344 web_input_to_password_info_[main_element] = password_info; | 1377 web_input_to_password_info_[main_element] = password_info; |
| 1345 password_to_username_[password_element] = username_element; | 1378 password_to_username_[password_element] = username_element; |
| 1346 web_element_to_password_info_key_[main_element] = key; | |
| 1347 } | 1379 } |
| 1348 } | 1380 } |
| 1349 | 1381 |
| 1350 void PasswordAutofillAgent::OnSetLoggingState(bool active) { | 1382 void PasswordAutofillAgent::OnSetLoggingState(bool active) { |
| 1351 logging_state_active_ = active; | 1383 logging_state_active_ = active; |
| 1352 } | 1384 } |
| 1353 | 1385 |
| 1354 void PasswordAutofillAgent::OnAutofillUsernameAndPasswordDataReceived( | 1386 void PasswordAutofillAgent::OnAutofillUsernameAndPasswordDataReceived( |
| 1355 const FormsPredictionsMap& predictions) { | 1387 const FormsPredictionsMap& predictions) { |
| 1356 form_predictions_.insert(predictions.begin(), predictions.end()); | 1388 form_predictions_.insert(predictions.begin(), predictions.end()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 1382 if (!password_form) | 1414 if (!password_form) |
| 1383 password_form.reset(new PasswordForm()); | 1415 password_form.reset(new PasswordForm()); |
| 1384 | 1416 |
| 1385 Send(new AutofillHostMsg_FocusedPasswordFormFound( | 1417 Send(new AutofillHostMsg_FocusedPasswordFormFound( |
| 1386 routing_id(), *password_form)); | 1418 routing_id(), *password_form)); |
| 1387 } | 1419 } |
| 1388 | 1420 |
| 1389 //////////////////////////////////////////////////////////////////////////////// | 1421 //////////////////////////////////////////////////////////////////////////////// |
| 1390 // PasswordAutofillAgent, private: | 1422 // PasswordAutofillAgent, private: |
| 1391 | 1423 |
| 1392 PasswordAutofillAgent::PasswordInfo::PasswordInfo() | |
| 1393 : password_was_edited_last(false), | |
| 1394 username_was_edited(false) { | |
| 1395 } | |
| 1396 | |
| 1397 bool PasswordAutofillAgent::ShowSuggestionPopup( | 1424 bool PasswordAutofillAgent::ShowSuggestionPopup( |
| 1398 const PasswordFormFillData& fill_data, | 1425 const PasswordInfo& password_info, |
| 1399 const blink::WebInputElement& user_input, | 1426 const blink::WebInputElement& user_input, |
| 1400 bool show_all, | 1427 bool show_all, |
| 1401 bool show_on_password_field) { | 1428 bool show_on_password_field) { |
| 1402 DCHECK(!user_input.isNull()); | 1429 DCHECK(!user_input.isNull()); |
| 1403 blink::WebFrame* frame = user_input.document().frame(); | 1430 blink::WebFrame* frame = user_input.document().frame(); |
| 1404 if (!frame) | 1431 if (!frame) |
| 1405 return false; | 1432 return false; |
| 1406 | 1433 |
| 1407 blink::WebView* webview = frame->view(); | 1434 blink::WebView* webview = frame->view(); |
| 1408 if (!webview) | 1435 if (!webview) |
| 1409 return false; | 1436 return false; |
| 1410 | 1437 |
| 1411 if (user_input.isPasswordField() && !user_input.isAutofilled() && | 1438 if (user_input.isPasswordField() && !user_input.isAutofilled() && |
| 1412 !user_input.value().isEmpty()) { | 1439 !user_input.value().isEmpty()) { |
| 1413 Send(new AutofillHostMsg_HidePopup(routing_id())); | 1440 Send(new AutofillHostMsg_HidePopup(routing_id())); |
| 1414 return false; | 1441 return false; |
| 1415 } | 1442 } |
| 1416 | 1443 |
| 1417 FormData form; | 1444 FormData form; |
| 1418 FormFieldData field; | 1445 FormFieldData field; |
| 1419 form_util::FindFormAndFieldForFormControlElement(user_input, &form, &field); | 1446 form_util::FindFormAndFieldForFormControlElement(user_input, &form, &field); |
| 1420 | 1447 |
| 1421 blink::WebInputElement selected_element = user_input; | |
| 1422 if (show_on_password_field && !selected_element.isPasswordField()) { | |
| 1423 WebInputToPasswordInfoMap::const_iterator iter = | |
| 1424 web_input_to_password_info_.find(user_input); | |
| 1425 DCHECK(iter != web_input_to_password_info_.end()); | |
| 1426 selected_element = iter->second.password_field; | |
| 1427 } | |
| 1428 | |
| 1429 blink::WebInputElement username; | |
| 1430 if (!show_on_password_field || !user_input.isPasswordField()) { | |
| 1431 username = user_input; | |
| 1432 } | |
| 1433 WebElementToPasswordInfoKeyMap::const_iterator key_it = | |
| 1434 web_element_to_password_info_key_.find(user_input); | |
| 1435 DCHECK(key_it != web_element_to_password_info_key_.end()); | |
| 1436 | |
| 1437 int options = 0; | 1448 int options = 0; |
| 1438 if (show_all) | 1449 if (show_all) |
| 1439 options |= SHOW_ALL; | 1450 options |= SHOW_ALL; |
| 1440 if (show_on_password_field) | 1451 if (show_on_password_field) |
| 1441 options |= IS_PASSWORD_FIELD; | 1452 options |= IS_PASSWORD_FIELD; |
| 1453 |
| 1442 base::string16 username_string( | 1454 base::string16 username_string( |
| 1443 username.isNull() ? base::string16() | 1455 user_input.isPasswordField() |
| 1444 : static_cast<base::string16>(user_input.value())); | 1456 ? base::string16() |
| 1457 : static_cast<base::string16>(user_input.value())); |
| 1445 | 1458 |
| 1446 Send(new AutofillHostMsg_ShowPasswordSuggestions( | 1459 Send(new AutofillHostMsg_ShowPasswordSuggestions( |
| 1447 routing_id(), | 1460 routing_id(), password_info.key, field.text_direction, username_string, |
| 1448 key_it->second, | 1461 options, |
| 1449 field.text_direction, | 1462 render_frame()->GetRenderView()->ElementBoundsInWindow(user_input))); |
| 1450 username_string, | |
| 1451 options, | |
| 1452 render_frame()->GetRenderView()->ElementBoundsInWindow( | |
| 1453 selected_element))); | |
| 1454 username_query_prefix_ = username_string; | 1463 username_query_prefix_ = username_string; |
| 1455 return CanShowSuggestion(fill_data, username_string, show_all); | 1464 return CanShowSuggestion(password_info.fill_data, username_string, show_all); |
| 1456 } | 1465 } |
| 1457 | 1466 |
| 1458 void PasswordAutofillAgent::FrameClosing() { | 1467 void PasswordAutofillAgent::FrameClosing() { |
| 1459 for (auto const& iter : web_input_to_password_info_) { | 1468 for (auto const& iter : web_input_to_password_info_) { |
| 1460 web_element_to_password_info_key_.erase(iter.first); | |
| 1461 password_to_username_.erase(iter.second.password_field); | 1469 password_to_username_.erase(iter.second.password_field); |
| 1462 } | 1470 } |
| 1463 web_input_to_password_info_.clear(); | 1471 web_input_to_password_info_.clear(); |
| 1464 provisionally_saved_form_.reset(); | 1472 provisionally_saved_form_.reset(); |
| 1465 nonscript_modified_values_.clear(); | 1473 nonscript_modified_values_.clear(); |
| 1466 } | 1474 } |
| 1467 | 1475 |
| 1468 bool PasswordAutofillAgent::FindLoginInfo(const blink::WebNode& node, | |
| 1469 blink::WebInputElement* found_input, | |
| 1470 PasswordInfo** found_password) { | |
| 1471 if (!node.isElementNode()) | |
| 1472 return false; | |
| 1473 | |
| 1474 blink::WebElement element = node.toConst<blink::WebElement>(); | |
| 1475 if (!element.hasHTMLTagName("input")) | |
| 1476 return false; | |
| 1477 | |
| 1478 *found_input = element.to<blink::WebInputElement>(); | |
| 1479 const blink::WebInputElement* username_element; // ignored | |
| 1480 return FindPasswordInfoForElement(*found_input, &username_element, | |
| 1481 found_password); | |
| 1482 } | |
| 1483 | |
| 1484 void PasswordAutofillAgent::ClearPreview( | 1476 void PasswordAutofillAgent::ClearPreview( |
| 1485 blink::WebInputElement* username, | 1477 blink::WebInputElement* username, |
| 1486 blink::WebInputElement* password) { | 1478 blink::WebInputElement* password) { |
| 1487 if (!username->suggestedValue().isEmpty()) { | 1479 if (!username->isNull() && !username->suggestedValue().isEmpty()) { |
| 1488 username->setSuggestedValue(blink::WebString()); | 1480 username->setSuggestedValue(blink::WebString()); |
| 1489 username->setAutofilled(was_username_autofilled_); | 1481 username->setAutofilled(was_username_autofilled_); |
| 1490 username->setSelectionRange(username_query_prefix_.length(), | 1482 username->setSelectionRange(username_query_prefix_.length(), |
| 1491 username->value().length()); | 1483 username->value().length()); |
| 1492 } | 1484 } |
| 1493 if (!password->suggestedValue().isEmpty()) { | 1485 if (!password->suggestedValue().isEmpty()) { |
| 1494 password->setSuggestedValue(blink::WebString()); | 1486 password->setSuggestedValue(blink::WebString()); |
| 1495 password->setAutofilled(was_password_autofilled_); | 1487 password->setAutofilled(was_password_autofilled_); |
| 1496 } | 1488 } |
| 1497 } | 1489 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1508 } | 1500 } |
| 1509 | 1501 |
| 1510 bool PasswordAutofillAgent::ProvisionallySavedPasswordIsValid() { | 1502 bool PasswordAutofillAgent::ProvisionallySavedPasswordIsValid() { |
| 1511 return provisionally_saved_form_ && | 1503 return provisionally_saved_form_ && |
| 1512 !provisionally_saved_form_->username_value.empty() && | 1504 !provisionally_saved_form_->username_value.empty() && |
| 1513 !(provisionally_saved_form_->password_value.empty() && | 1505 !(provisionally_saved_form_->password_value.empty() && |
| 1514 provisionally_saved_form_->new_password_value.empty()); | 1506 provisionally_saved_form_->new_password_value.empty()); |
| 1515 } | 1507 } |
| 1516 | 1508 |
| 1517 } // namespace autofill | 1509 } // namespace autofill |
| OLD | NEW |