Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(535)

Side by Side Diff: components/autofill/content/renderer/password_autofill_agent.cc

Issue 166043006: Add password manager autocomplete suggestion when a username element in clicked. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on ToT Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « components/autofill/content/renderer/password_autofill_agent.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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,
1023 &password, 1028 &password,
1024 fill_data, 1029 fill_data,
1025 false /* exact_username_match */, 1030 false /* exact_username_match */,
1026 true /* set_selection */); 1031 true /* set_selection */);
1027 #endif 1032 #endif
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1074 username->setSelectionRange(username_selection_start_, 1079 username->setSelectionRange(username_selection_start_,
1075 username->value().length()); 1080 username->value().length());
1076 } 1081 }
1077 if (!password->suggestedValue().isEmpty()) { 1082 if (!password->suggestedValue().isEmpty()) {
1078 password->setSuggestedValue(blink::WebString()); 1083 password->setSuggestedValue(blink::WebString());
1079 password->setAutofilled(was_password_autofilled_); 1084 password->setAutofilled(was_password_autofilled_);
1080 } 1085 }
1081 } 1086 }
1082 1087
1083 } // namespace autofill 1088 } // namespace autofill
OLDNEW
« no previous file with comments | « components/autofill/content/renderer/password_autofill_agent.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698