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

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: Fixed a comment and cleaned up a browser test Created 6 years, 9 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
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 299 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 310
311 if (!element.isText() || !IsElementAutocompletable(element) || 311 if (!element.isText() || !IsElementAutocompletable(element) ||
312 !IsElementAutocompletable(password)) { 312 !IsElementAutocompletable(password)) {
313 return false; 313 return false;
314 } 314 }
315 315
316 // Don't inline autocomplete if the user is deleting, that would be confusing. 316 // Don't inline autocomplete if the user is deleting, that would be confusing.
317 // But refresh the popup. Note, since this is ours, return true to signal 317 // But refresh the popup. Note, since this is ours, return true to signal
318 // no further processing is required. 318 // no further processing is required.
319 if (iter->second.backspace_pressed_last) { 319 if (iter->second.backspace_pressed_last) {
320 ShowSuggestionPopup(iter->second.fill_data, username); 320 ShowSuggestionPopup(iter->second.fill_data, username, false);
321 return true; 321 return true;
322 } 322 }
323 323
324 blink::WebString name = element.nameForAutofill(); 324 blink::WebString name = element.nameForAutofill();
325 if (name.isEmpty()) 325 if (name.isEmpty())
326 return false; // If the field has no name, then we won't have values. 326 return false; // If the field has no name, then we won't have values.
327 327
328 // Don't attempt to autofill with values that are too large. 328 // Don't attempt to autofill with values that are too large.
329 if (element.value().length() > kMaximumTextSizeForAutocomplete) 329 if (element.value().length() > kMaximumTextSizeForAutocomplete)
330 return false; 330 return false;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
369 } 369 }
370 370
371 bool PasswordAutofillAgent::DidClearAutofillSelection( 371 bool PasswordAutofillAgent::DidClearAutofillSelection(
372 const blink::WebNode& node) { 372 const blink::WebNode& node) {
373 blink::WebInputElement input; 373 blink::WebInputElement input;
374 PasswordInfo password; 374 PasswordInfo password;
375 return FindLoginInfo(node, &input, &password); 375 return FindLoginInfo(node, &input, &password);
376 } 376 }
377 377
378 bool PasswordAutofillAgent::ShowSuggestions( 378 bool PasswordAutofillAgent::ShowSuggestions(
379 const blink::WebInputElement& element) { 379 const blink::WebInputElement& element,
380 bool show_all) {
380 LoginToPasswordInfoMap::const_iterator iter = 381 LoginToPasswordInfoMap::const_iterator iter =
381 login_to_password_info_.find(element); 382 login_to_password_info_.find(element);
382 if (iter == login_to_password_info_.end()) 383 if (iter == login_to_password_info_.end())
383 return false; 384 return false;
384 385
385 // If autocomplete='off' is set on the form elements, no suggestion dialog 386 // If autocomplete='off' is set on the form elements, no suggestion dialog
386 // should be shown. However, return |true| to indicate that this is a known 387 // should be shown. However, return |true| to indicate that this is a known
387 // password form and that the request to show suggestions has been handled (as 388 // password form and that the request to show suggestions has been handled (as
388 // a no-op). 389 // a no-op).
389 if (!IsElementAutocompletable(element) || 390 if (!IsElementAutocompletable(element) ||
390 !IsElementAutocompletable(iter->second.password_field)) 391 !IsElementAutocompletable(iter->second.password_field))
391 return true; 392 return true;
392 393
393 return ShowSuggestionPopup(iter->second.fill_data, element); 394 return ShowSuggestionPopup(iter->second.fill_data, element, show_all);
394 } 395 }
395 396
396 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( 397 bool PasswordAutofillAgent::OriginCanAccessPasswordManager(
397 const blink::WebSecurityOrigin& origin) { 398 const blink::WebSecurityOrigin& origin) {
398 return origin.canAccessPasswordManager(); 399 return origin.canAccessPasswordManager();
399 } 400 }
400 401
401 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) { 402 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) {
402 SendPasswordForms(frame, false /* only_visible */); 403 SendPasswordForms(frame, false /* only_visible */);
403 } 404 }
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
646 } 647 }
647 } 648 }
648 649
649 //////////////////////////////////////////////////////////////////////////////// 650 ////////////////////////////////////////////////////////////////////////////////
650 // PasswordAutofillAgent, private: 651 // PasswordAutofillAgent, private:
651 652
652 void PasswordAutofillAgent::GetSuggestions( 653 void PasswordAutofillAgent::GetSuggestions(
653 const PasswordFormFillData& fill_data, 654 const PasswordFormFillData& fill_data,
654 const base::string16& input, 655 const base::string16& input,
655 std::vector<base::string16>* suggestions, 656 std::vector<base::string16>* suggestions,
656 std::vector<base::string16>* realms) { 657 std::vector<base::string16>* realms,
657 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) { 658 bool show_all) {
659 if (show_all ||
660 StartsWith(fill_data.basic_data.fields[0].value, input, false)) {
658 suggestions->push_back(fill_data.basic_data.fields[0].value); 661 suggestions->push_back(fill_data.basic_data.fields[0].value);
659 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); 662 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm));
660 } 663 }
661 664
662 for (PasswordFormFillData::LoginCollection::const_iterator iter = 665 for (PasswordFormFillData::LoginCollection::const_iterator iter =
663 fill_data.additional_logins.begin(); 666 fill_data.additional_logins.begin();
664 iter != fill_data.additional_logins.end(); ++iter) { 667 iter != fill_data.additional_logins.end(); ++iter) {
665 if (StartsWith(iter->first, input, false)) { 668 if (show_all || StartsWith(iter->first, input, false)) {
666 suggestions->push_back(iter->first); 669 suggestions->push_back(iter->first);
667 realms->push_back(base::UTF8ToUTF16(iter->second.realm)); 670 realms->push_back(base::UTF8ToUTF16(iter->second.realm));
668 } 671 }
669 } 672 }
670 673
671 for (PasswordFormFillData::UsernamesCollection::const_iterator iter = 674 for (PasswordFormFillData::UsernamesCollection::const_iterator iter =
672 fill_data.other_possible_usernames.begin(); 675 fill_data.other_possible_usernames.begin();
673 iter != fill_data.other_possible_usernames.end(); ++iter) { 676 iter != fill_data.other_possible_usernames.end(); ++iter) {
674 for (size_t i = 0; i < iter->second.size(); ++i) { 677 for (size_t i = 0; i < iter->second.size(); ++i) {
675 if (StartsWith(iter->second[i], input, false)) { 678 if (show_all || StartsWith(iter->second[i], input, false)) {
676 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; 679 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN;
677 suggestions->push_back(iter->second[i]); 680 suggestions->push_back(iter->second[i]);
678 realms->push_back(base::UTF8ToUTF16(iter->first.realm)); 681 realms->push_back(base::UTF8ToUTF16(iter->first.realm));
679 } 682 }
680 } 683 }
681 } 684 }
682 } 685 }
683 686
684 bool PasswordAutofillAgent::ShowSuggestionPopup( 687 bool PasswordAutofillAgent::ShowSuggestionPopup(
685 const PasswordFormFillData& fill_data, 688 const PasswordFormFillData& fill_data,
686 const blink::WebInputElement& user_input) { 689 const blink::WebInputElement& user_input,
690 bool show_all) {
687 blink::WebFrame* frame = user_input.document().frame(); 691 blink::WebFrame* frame = user_input.document().frame();
688 if (!frame) 692 if (!frame)
689 return false; 693 return false;
690 694
691 blink::WebView* webview = frame->view(); 695 blink::WebView* webview = frame->view();
692 if (!webview) 696 if (!webview)
693 return false; 697 return false;
694 698
695 std::vector<base::string16> suggestions; 699 std::vector<base::string16> suggestions;
696 std::vector<base::string16> realms; 700 std::vector<base::string16> realms;
697 GetSuggestions(fill_data, user_input.value(), &suggestions, &realms); 701 GetSuggestions(
702 fill_data, user_input.value(), &suggestions, &realms, show_all);
698 DCHECK_EQ(suggestions.size(), realms.size()); 703 DCHECK_EQ(suggestions.size(), realms.size());
699 704
700 FormData form; 705 FormData form;
701 FormFieldData field; 706 FormFieldData field;
702 FindFormAndFieldForInputElement( 707 FindFormAndFieldForInputElement(
703 user_input, &form, &field, REQUIRE_NONE); 708 user_input, &form, &field, REQUIRE_NONE);
704 709
705 blink::WebInputElement selected_element = user_input; 710 blink::WebInputElement selected_element = user_input;
706 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); 711 gfx::Rect bounding_box(selected_element.boundsInViewportSpace());
707 712
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
854 blink::WebInputElement password = password_input; 859 blink::WebInputElement password = password_input;
855 860
856 // Don't inline autocomplete if the caret is not at the end. 861 // Don't inline autocomplete if the caret is not at the end.
857 // TODO(jcivelli): is there a better way to test the caret location? 862 // TODO(jcivelli): is there a better way to test the caret location?
858 if (username.selectionStart() != username.selectionEnd() || 863 if (username.selectionStart() != username.selectionEnd() ||
859 username.selectionEnd() != static_cast<int>(username.value().length())) { 864 username.selectionEnd() != static_cast<int>(username.value().length())) {
860 return; 865 return;
861 } 866 }
862 867
863 // Show the popup with the list of available usernames. 868 // Show the popup with the list of available usernames.
864 ShowSuggestionPopup(fill_data, username); 869 ShowSuggestionPopup(fill_data, username, false);
865
866 870
867 #if !defined(OS_ANDROID) 871 #if !defined(OS_ANDROID)
868 // Fill the user and password field with the most relevant match. Android 872 // Fill the user and password field with the most relevant match. Android
869 // only fills in the fields after the user clicks on the suggestion popup. 873 // only fills in the fields after the user clicks on the suggestion popup.
870 FillUserNameAndPassword(&username, &password, fill_data, 874 FillUserNameAndPassword(&username, &password, fill_data,
871 false /* exact_username_match */, 875 false /* exact_username_match */,
872 true /* set_selection */); 876 true /* set_selection */);
873 #endif 877 #endif
874 } 878 }
875 879
(...skipping 29 matching lines...) Expand all
905 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); 909 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input);
906 if (iter == login_to_password_info_.end()) 910 if (iter == login_to_password_info_.end())
907 return false; 911 return false;
908 912
909 *found_input = input; 913 *found_input = input;
910 *found_password = iter->second; 914 *found_password = iter->second;
911 return true; 915 return true;
912 } 916 }
913 917
914 } // namespace autofill 918 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698