| 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 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 | 331 |
| 332 if (!element.isText() || !IsElementAutocompletable(element) || | 332 if (!element.isText() || !IsElementAutocompletable(element) || |
| 333 !IsElementAutocompletable(password)) { | 333 !IsElementAutocompletable(password)) { |
| 334 return false; | 334 return false; |
| 335 } | 335 } |
| 336 | 336 |
| 337 // Don't inline autocomplete if the user is deleting, that would be confusing. | 337 // Don't inline autocomplete if the user is deleting, that would be confusing. |
| 338 // But refresh the popup. Note, since this is ours, return true to signal | 338 // But refresh the popup. Note, since this is ours, return true to signal |
| 339 // no further processing is required. | 339 // no further processing is required. |
| 340 if (iter->second.backspace_pressed_last) { | 340 if (iter->second.backspace_pressed_last) { |
| 341 ShowSuggestionPopup(iter->second.fill_data, username); | 341 ShowSuggestionPopup(iter->second.fill_data, username, false); |
| 342 return true; | 342 return true; |
| 343 } | 343 } |
| 344 | 344 |
| 345 blink::WebString name = element.nameForAutofill(); | 345 blink::WebString name = element.nameForAutofill(); |
| 346 if (name.isEmpty()) | 346 if (name.isEmpty()) |
| 347 return false; // If the field has no name, then we won't have values. | 347 return false; // If the field has no name, then we won't have values. |
| 348 | 348 |
| 349 // Don't attempt to autofill with values that are too large. | 349 // Don't attempt to autofill with values that are too large. |
| 350 if (element.value().length() > kMaximumTextSizeForAutocomplete) | 350 if (element.value().length() > kMaximumTextSizeForAutocomplete) |
| 351 return false; | 351 return false; |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 blink::WebInputElement username_element; | 429 blink::WebInputElement username_element; |
| 430 PasswordInfo password_info; | 430 PasswordInfo password_info; |
| 431 if (!FindLoginInfo(node, &username_element, &password_info)) | 431 if (!FindLoginInfo(node, &username_element, &password_info)) |
| 432 return false; | 432 return false; |
| 433 | 433 |
| 434 ClearPreview(&username_element, &password_info.password_field); | 434 ClearPreview(&username_element, &password_info.password_field); |
| 435 return true; | 435 return true; |
| 436 } | 436 } |
| 437 | 437 |
| 438 bool PasswordAutofillAgent::ShowSuggestions( | 438 bool PasswordAutofillAgent::ShowSuggestions( |
| 439 const blink::WebInputElement& element) { | 439 const blink::WebInputElement& element, |
| 440 bool show_all) { |
| 440 LoginToPasswordInfoMap::const_iterator iter = | 441 LoginToPasswordInfoMap::const_iterator iter = |
| 441 login_to_password_info_.find(element); | 442 login_to_password_info_.find(element); |
| 442 if (iter == login_to_password_info_.end()) | 443 if (iter == login_to_password_info_.end()) |
| 443 return false; | 444 return false; |
| 444 | 445 |
| 445 // If autocomplete='off' is set on the form elements, no suggestion dialog | 446 // If autocomplete='off' is set on the form elements, no suggestion dialog |
| 446 // should be shown. However, return |true| to indicate that this is a known | 447 // should be shown. However, return |true| to indicate that this is a known |
| 447 // password form and that the request to show suggestions has been handled (as | 448 // password form and that the request to show suggestions has been handled (as |
| 448 // a no-op). | 449 // a no-op). |
| 449 if (!IsElementAutocompletable(element) || | 450 if (!IsElementAutocompletable(element) || |
| 450 !IsElementAutocompletable(iter->second.password_field)) | 451 !IsElementAutocompletable(iter->second.password_field)) |
| 451 return true; | 452 return true; |
| 452 | 453 |
| 453 return ShowSuggestionPopup(iter->second.fill_data, element); | 454 return ShowSuggestionPopup(iter->second.fill_data, element, show_all); |
| 454 } | 455 } |
| 455 | 456 |
| 456 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( | 457 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( |
| 457 const blink::WebSecurityOrigin& origin) { | 458 const blink::WebSecurityOrigin& origin) { |
| 458 return origin.canAccessPasswordManager(); | 459 return origin.canAccessPasswordManager(); |
| 459 } | 460 } |
| 460 | 461 |
| 461 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) { | 462 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) { |
| 462 SendPasswordForms(frame, false /* only_visible */); | 463 SendPasswordForms(frame, false /* only_visible */); |
| 463 } | 464 } |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 804 logging_state_active_ = active; | 805 logging_state_active_ = active; |
| 805 } | 806 } |
| 806 | 807 |
| 807 //////////////////////////////////////////////////////////////////////////////// | 808 //////////////////////////////////////////////////////////////////////////////// |
| 808 // PasswordAutofillAgent, private: | 809 // PasswordAutofillAgent, private: |
| 809 | 810 |
| 810 void PasswordAutofillAgent::GetSuggestions( | 811 void PasswordAutofillAgent::GetSuggestions( |
| 811 const PasswordFormFillData& fill_data, | 812 const PasswordFormFillData& fill_data, |
| 812 const base::string16& input, | 813 const base::string16& input, |
| 813 std::vector<base::string16>* suggestions, | 814 std::vector<base::string16>* suggestions, |
| 814 std::vector<base::string16>* realms) { | 815 std::vector<base::string16>* realms, |
| 815 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) { | 816 bool show_all) { |
| 817 if (show_all || |
| 818 StartsWith(fill_data.basic_data.fields[0].value, input, false)) { |
| 816 suggestions->push_back(fill_data.basic_data.fields[0].value); | 819 suggestions->push_back(fill_data.basic_data.fields[0].value); |
| 817 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); | 820 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); |
| 818 } | 821 } |
| 819 | 822 |
| 820 for (PasswordFormFillData::LoginCollection::const_iterator iter = | 823 for (PasswordFormFillData::LoginCollection::const_iterator iter = |
| 821 fill_data.additional_logins.begin(); | 824 fill_data.additional_logins.begin(); |
| 822 iter != fill_data.additional_logins.end(); | 825 iter != fill_data.additional_logins.end(); |
| 823 ++iter) { | 826 ++iter) { |
| 824 if (StartsWith(iter->first, input, false)) { | 827 if (show_all || StartsWith(iter->first, input, false)) { |
| 825 suggestions->push_back(iter->first); | 828 suggestions->push_back(iter->first); |
| 826 realms->push_back(base::UTF8ToUTF16(iter->second.realm)); | 829 realms->push_back(base::UTF8ToUTF16(iter->second.realm)); |
| 827 } | 830 } |
| 828 } | 831 } |
| 829 | 832 |
| 830 for (PasswordFormFillData::UsernamesCollection::const_iterator iter = | 833 for (PasswordFormFillData::UsernamesCollection::const_iterator iter = |
| 831 fill_data.other_possible_usernames.begin(); | 834 fill_data.other_possible_usernames.begin(); |
| 832 iter != fill_data.other_possible_usernames.end(); | 835 iter != fill_data.other_possible_usernames.end(); |
| 833 ++iter) { | 836 ++iter) { |
| 834 for (size_t i = 0; i < iter->second.size(); ++i) { | 837 for (size_t i = 0; i < iter->second.size(); ++i) { |
| 835 if (StartsWith(iter->second[i], input, false)) { | 838 if (show_all || StartsWith(iter->second[i], input, false)) { |
| 836 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; | 839 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; |
| 837 suggestions->push_back(iter->second[i]); | 840 suggestions->push_back(iter->second[i]); |
| 838 realms->push_back(base::UTF8ToUTF16(iter->first.realm)); | 841 realms->push_back(base::UTF8ToUTF16(iter->first.realm)); |
| 839 } | 842 } |
| 840 } | 843 } |
| 841 } | 844 } |
| 842 } | 845 } |
| 843 | 846 |
| 844 bool PasswordAutofillAgent::ShowSuggestionPopup( | 847 bool PasswordAutofillAgent::ShowSuggestionPopup( |
| 845 const PasswordFormFillData& fill_data, | 848 const PasswordFormFillData& fill_data, |
| 846 const blink::WebInputElement& user_input) { | 849 const blink::WebInputElement& user_input, |
| 850 bool show_all) { |
| 847 blink::WebFrame* frame = user_input.document().frame(); | 851 blink::WebFrame* frame = user_input.document().frame(); |
| 848 if (!frame) | 852 if (!frame) |
| 849 return false; | 853 return false; |
| 850 | 854 |
| 851 blink::WebView* webview = frame->view(); | 855 blink::WebView* webview = frame->view(); |
| 852 if (!webview) | 856 if (!webview) |
| 853 return false; | 857 return false; |
| 854 | 858 |
| 855 std::vector<base::string16> suggestions; | 859 std::vector<base::string16> suggestions; |
| 856 std::vector<base::string16> realms; | 860 std::vector<base::string16> realms; |
| 857 GetSuggestions(fill_data, user_input.value(), &suggestions, &realms); | 861 GetSuggestions( |
| 862 fill_data, user_input.value(), &suggestions, &realms, show_all); |
| 858 DCHECK_EQ(suggestions.size(), realms.size()); | 863 DCHECK_EQ(suggestions.size(), realms.size()); |
| 859 | 864 |
| 860 FormData form; | 865 FormData form; |
| 861 FormFieldData field; | 866 FormFieldData field; |
| 862 FindFormAndFieldForFormControlElement( | 867 FindFormAndFieldForFormControlElement( |
| 863 user_input, &form, &field, REQUIRE_NONE); | 868 user_input, &form, &field, REQUIRE_NONE); |
| 864 | 869 |
| 865 blink::WebInputElement selected_element = user_input; | 870 blink::WebInputElement selected_element = user_input; |
| 866 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); | 871 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); |
| 867 | 872 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1007 blink::WebInputElement password = password_input; | 1012 blink::WebInputElement password = password_input; |
| 1008 | 1013 |
| 1009 // Don't inline autocomplete if the caret is not at the end. | 1014 // Don't inline autocomplete if the caret is not at the end. |
| 1010 // TODO(jcivelli): is there a better way to test the caret location? | 1015 // TODO(jcivelli): is there a better way to test the caret location? |
| 1011 if (username.selectionStart() != username.selectionEnd() || | 1016 if (username.selectionStart() != username.selectionEnd() || |
| 1012 username.selectionEnd() != static_cast<int>(username.value().length())) { | 1017 username.selectionEnd() != static_cast<int>(username.value().length())) { |
| 1013 return; | 1018 return; |
| 1014 } | 1019 } |
| 1015 | 1020 |
| 1016 // Show the popup with the list of available usernames. | 1021 // Show the popup with the list of available usernames. |
| 1017 ShowSuggestionPopup(fill_data, username); | 1022 ShowSuggestionPopup(fill_data, username, false); |
| 1018 | 1023 |
| 1019 #if !defined(OS_ANDROID) | 1024 #if !defined(OS_ANDROID) |
| 1020 // Fill the user and password field with the most relevant match. Android | 1025 // Fill the user and password field with the most relevant match. Android |
| 1021 // only fills in the fields after the user clicks on the suggestion popup. | 1026 // only fills in the fields after the user clicks on the suggestion popup. |
| 1022 FillUserNameAndPassword(&username, | 1027 FillUserNameAndPassword(&username, &password, fill_data, |
| 1023 &password, | |
| 1024 fill_data, | |
| 1025 false /* exact_username_match */, | 1028 false /* exact_username_match */, |
| 1026 true /* set_selection */); | 1029 true /* set_selection */); |
| 1027 #endif | 1030 #endif |
| 1028 } | 1031 } |
| 1029 | 1032 |
| 1030 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { | 1033 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { |
| 1031 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); | 1034 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
| 1032 iter != login_to_password_info_.end();) { | 1035 iter != login_to_password_info_.end();) { |
| 1033 if (iter->first.document().frame() == frame) | 1036 if (iter->first.document().frame() == frame) |
| 1034 login_to_password_info_.erase(iter++); | 1037 login_to_password_info_.erase(iter++); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1074 username->setSelectionRange(username_selection_start_, | 1077 username->setSelectionRange(username_selection_start_, |
| 1075 username->value().length()); | 1078 username->value().length()); |
| 1076 } | 1079 } |
| 1077 if (!password->suggestedValue().isEmpty()) { | 1080 if (!password->suggestedValue().isEmpty()) { |
| 1078 password->setSuggestedValue(blink::WebString()); | 1081 password->setSuggestedValue(blink::WebString()); |
| 1079 password->setAutofilled(was_password_autofilled_); | 1082 password->setAutofilled(was_password_autofilled_); |
| 1080 } | 1083 } |
| 1081 } | 1084 } |
| 1082 | 1085 |
| 1083 } // namespace autofill | 1086 } // namespace autofill |
| OLD | NEW |