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

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

Issue 492043003: Fill on account select in the password manager (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase on ToT Created 6 years, 1 month 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/command_line.h"
8 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
9 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
10 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
11 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
12 #include "components/autofill/content/common/autofill_messages.h" 13 #include "components/autofill/content/common/autofill_messages.h"
13 #include "components/autofill/content/renderer/form_autofill_util.h" 14 #include "components/autofill/content/renderer/form_autofill_util.h"
14 #include "components/autofill/content/renderer/password_form_conversion_utils.h" 15 #include "components/autofill/content/renderer/password_form_conversion_utils.h"
15 #include "components/autofill/content/renderer/renderer_save_password_progress_l ogger.h" 16 #include "components/autofill/content/renderer/renderer_save_password_progress_l ogger.h"
17 #include "components/autofill/core/common/autofill_switches.h"
16 #include "components/autofill/core/common/form_field_data.h" 18 #include "components/autofill/core/common/form_field_data.h"
17 #include "components/autofill/core/common/password_autofill_util.h" 19 #include "components/autofill/core/common/password_autofill_util.h"
18 #include "components/autofill/core/common/password_form.h" 20 #include "components/autofill/core/common/password_form.h"
19 #include "components/autofill/core/common/password_form_fill_data.h" 21 #include "components/autofill/core/common/password_form_fill_data.h"
20 #include "content/public/renderer/document_state.h" 22 #include "content/public/renderer/document_state.h"
21 #include "content/public/renderer/navigation_state.h" 23 #include "content/public/renderer/navigation_state.h"
22 #include "content/public/renderer/render_view.h" 24 #include "content/public/renderer/render_view.h"
23 #include "third_party/WebKit/public/platform/WebVector.h" 25 #include "third_party/WebKit/public/platform/WebVector.h"
24 #include "third_party/WebKit/public/web/WebAutofillClient.h" 26 #include "third_party/WebKit/public/web/WebAutofillClient.h"
25 #include "third_party/WebKit/public/web/WebDocument.h" 27 #include "third_party/WebKit/public/web/WebDocument.h"
26 #include "third_party/WebKit/public/web/WebElement.h" 28 #include "third_party/WebKit/public/web/WebElement.h"
27 #include "third_party/WebKit/public/web/WebFormElement.h" 29 #include "third_party/WebKit/public/web/WebFormElement.h"
28 #include "third_party/WebKit/public/web/WebInputEvent.h" 30 #include "third_party/WebKit/public/web/WebInputEvent.h"
29 #include "third_party/WebKit/public/web/WebLocalFrame.h" 31 #include "third_party/WebKit/public/web/WebLocalFrame.h"
30 #include "third_party/WebKit/public/web/WebNode.h" 32 #include "third_party/WebKit/public/web/WebNode.h"
31 #include "third_party/WebKit/public/web/WebNodeList.h" 33 #include "third_party/WebKit/public/web/WebNodeList.h"
32 #include "third_party/WebKit/public/web/WebSecurityOrigin.h" 34 #include "third_party/WebKit/public/web/WebSecurityOrigin.h"
33 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h" 35 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
34 #include "third_party/WebKit/public/web/WebView.h" 36 #include "third_party/WebKit/public/web/WebView.h"
35 #include "ui/base/page_transition_types.h" 37 #include "ui/base/page_transition_types.h"
36 #include "ui/events/keycodes/keyboard_codes.h" 38 #include "ui/events/keycodes/keyboard_codes.h"
37 #include "url/gurl.h" 39 #include "url/gurl.h"
38 40
39 namespace autofill { 41 namespace autofill {
40 namespace { 42 namespace {
41 43
44 enum FillUserNameAndPasswordOptions {
45 EXACT_USERNAME_MATCH = 1 << 0,
46 SET_SELECTION = 1 << 1,
47 FILL_PREFERRED_USERNAME = 1 << 2
48 };
49
42 // The size above which we stop triggering autocomplete. 50 // The size above which we stop triggering autocomplete.
43 static const size_t kMaximumTextSizeForAutocomplete = 1000; 51 static const size_t kMaximumTextSizeForAutocomplete = 1000;
44 52
45 // Maps element names to the actual elements to simplify form filling. 53 // Maps element names to the actual elements to simplify form filling.
46 typedef std::map<base::string16, blink::WebInputElement> FormInputElementMap; 54 typedef std::map<base::string16, blink::WebInputElement> FormInputElementMap;
47 55
48 // Use the shorter name when referencing SavePasswordProgressLogger::StringID 56 // Use the shorter name when referencing SavePasswordProgressLogger::StringID
49 // values to spare line breaks. The code provides enough context for that 57 // values to spare line breaks. The code provides enough context for that
50 // already. 58 // already.
51 typedef SavePasswordProgressLogger Logger; 59 typedef SavePasswordProgressLogger Logger;
52 60
53 // Utility struct for form lookup and autofill. When we parse the DOM to look up 61 // Utility struct for form lookup and autofill. When we parse the DOM to look up
54 // a form, in addition to action and origin URL's we have to compare all 62 // a form, in addition to action and origin URL's we have to compare all
55 // necessary form elements. To avoid having to look these up again when we want 63 // necessary form elements. To avoid having to look these up again when we want
56 // to fill the form, the FindFormElements function stores the pointers 64 // to fill the form, the FindFormElements function stores the pointers
57 // in a FormElements* result, referenced to ensure they are safe to use. 65 // in a FormElements* result, referenced to ensure they are safe to use.
58 struct FormElements { 66 struct FormElements {
59 blink::WebFormElement form_element; 67 blink::WebFormElement form_element;
60 FormInputElementMap input_elements; 68 FormInputElementMap input_elements;
61 }; 69 };
62 70
63 typedef std::vector<FormElements*> FormElementsList; 71 typedef std::vector<FormElements*> FormElementsList;
64 72
73 bool ShouldFillOnAccountSelect() {
74 if (CommandLine::ForCurrentProcess()->HasSwitch(
75 switches::kEnableFillOnAccountSelect)) {
76 return true;
77 }
78
79 // This is made explicit in anticiption of experimental groups being added.
80 if (CommandLine::ForCurrentProcess()->HasSwitch(
81 switches::kDisableFillOnAccountSelect)) {
82 return false;
83 }
84
85 // TODO(jww): Add experimental groups check here.
86
87 return false;
88 }
89
65 // Helper to search the given form element for the specified input elements 90 // Helper to search the given form element for the specified input elements
66 // in |data|, and add results to |result|. 91 // in |data|, and add results to |result|.
67 static bool FindFormInputElements(blink::WebFormElement* fe, 92 static bool FindFormInputElements(blink::WebFormElement* fe,
68 const FormData& data, 93 const FormData& data,
69 FormElements* result) { 94 FormElements* result) {
70 const bool username_is_present = !data.fields[0].name.empty(); 95 const bool username_is_present = !data.fields[0].name.empty();
71 96
72 // Loop through the list of elements we need to find on the form in order to 97 // Loop through the list of elements we need to find on the form in order to
73 // autofill it. If we don't find any one of them, abort processing this 98 // autofill it. If we don't find any one of them, abort processing this
74 // form; it can't be the right one. 99 // form; it can't be the right one.
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 299 }
275 } 300 }
276 301
277 return false; 302 return false;
278 } 303 }
279 304
280 // This function attempts to fill |username_element| and |password_element| 305 // This function attempts to fill |username_element| and |password_element|
281 // with values from |fill_data|. The |password_element| will only have the 306 // with values from |fill_data|. The |password_element| will only have the
282 // |suggestedValue| set, and will be registered for copying that to the real 307 // |suggestedValue| set, and will be registered for copying that to the real
283 // value through |registration_callback|. The function returns true when 308 // value through |registration_callback|. The function returns true when
284 // selected username comes from |fill_data.other_possible_usernames|. 309 // selected username comes from |fill_data.other_possible_usernames|. |options|
310 // should be a bitwise mask of FillUserNameAndPasswordOptions values.
285 bool FillUserNameAndPassword( 311 bool FillUserNameAndPassword(
286 blink::WebInputElement* username_element, 312 blink::WebInputElement* username_element,
287 blink::WebInputElement* password_element, 313 blink::WebInputElement* password_element,
288 const PasswordFormFillData& fill_data, 314 const PasswordFormFillData& fill_data,
289 bool exact_username_match, 315 const int options,
290 bool set_selection,
291 base::Callback<void(blink::WebInputElement*)> registration_callback) { 316 base::Callback<void(blink::WebInputElement*)> registration_callback) {
317 bool exact_username_match = (options & EXACT_USERNAME_MATCH) != 0;
318 bool set_selection = (options & SET_SELECTION) != 0;
292 bool other_possible_username_selected = false; 319 bool other_possible_username_selected = false;
293 // Don't fill username if password can't be set. 320 // Don't fill username if password can't be set.
294 if (!IsElementAutocompletable(*password_element)) 321 if (!IsElementAutocompletable(*password_element))
295 return false; 322 return false;
296 323
297 base::string16 current_username; 324 base::string16 current_username;
298 if (!username_element->isNull()) { 325 if (!username_element->isNull()) {
299 current_username = username_element->value(); 326 current_username = username_element->value();
300 } 327 }
301 328
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 } 403 }
377 404
378 // Attempts to fill |username_element| and |password_element| with the 405 // Attempts to fill |username_element| and |password_element| with the
379 // |fill_data|. Will use the data corresponding to the preferred username, 406 // |fill_data|. Will use the data corresponding to the preferred username,
380 // unless the |username_element| already has a value set. In that case, 407 // unless the |username_element| already has a value set. In that case,
381 // attempts to fill the password matching the already filled username, if 408 // attempts to fill the password matching the already filled username, if
382 // such a password exists. The |password_element| will have the 409 // such a password exists. The |password_element| will have the
383 // |suggestedValue| set, and |suggestedValue| will be registered for copying to 410 // |suggestedValue| set, and |suggestedValue| will be registered for copying to
384 // the real value through |registration_callback|. Returns true when the 411 // the real value through |registration_callback|. Returns true when the
385 // username gets selected from |other_possible_usernames|, else returns false. 412 // username gets selected from |other_possible_usernames|, else returns false.
386 bool FillFormOnPasswordRecieved( 413 bool FillFormOnPasswordReceived(
387 const PasswordFormFillData& fill_data, 414 const PasswordFormFillData& fill_data,
388 blink::WebInputElement username_element, 415 blink::WebInputElement username_element,
389 blink::WebInputElement password_element, 416 blink::WebInputElement password_element,
390 base::Callback<void(blink::WebInputElement*)> registration_callback) { 417 base::Callback<void(blink::WebInputElement*)> registration_callback) {
391 // Do not fill if the password field is in an iframe. 418 // Do not fill if the password field is in an iframe.
392 DCHECK(password_element.document().frame()); 419 DCHECK(password_element.document().frame());
393 if (password_element.document().frame()->parent()) 420 if (password_element.document().frame()->parent())
394 return false; 421 return false;
395 422
396 bool form_contains_username_field = FillDataContainsUsername(fill_data); 423 bool form_contains_username_field = FillDataContainsUsername(fill_data);
397 if (!ShouldIgnoreAutocompleteOffForPasswordFields() && 424 if (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
398 form_contains_username_field && !username_element.form().autoComplete()) 425 form_contains_username_field && !username_element.form().autoComplete())
399 return false; 426 return false;
400 427
401 // If we can't modify the password, don't try to set the username 428 // If we can't modify the password, don't try to set the username
402 if (!IsElementAutocompletable(password_element)) 429 if (!IsElementAutocompletable(password_element))
403 return false; 430 return false;
404 431
405 // Try to set the username to the preferred name, but only if the field 432 // Try to set the username to the preferred name, but only if:
406 // can be set and isn't prefilled. 433 // (a) The username element is autocompletable, and
407 if (form_contains_username_field && 434 // (b) The fill-on-account-select flag is not set, and
408 IsElementAutocompletable(username_element) && 435 // (b) The username element isn't prefilled
Garrett Casto 2014/11/04 23:35:30 Is that last line supposed to be (c)?
jww 2014/11/06 21:28:56 Yup :-)
409 username_element.value().isEmpty()) { 436 //
410 // TODO(tkent): Check maxlength and pattern. 437 // If (a) is true, but (b) is false, then just mark the username element as
411 username_element.setValue(fill_data.basic_data.fields[0].value, true); 438 // autofilled and return so the fill step is skipped.
439 //
440 // If (a) is false, but (b) is true, then the username element should not be
441 // autofilled, but the user should still be able to select to fill the
442 // password element, so the password element must be marked as autofilled and
443 // the fill step should also be skipped.
444 if (IsElementAutocompletable(username_element)) {
Garrett Casto 2014/11/04 23:35:30 I think that you dropped the form_contains_usernam
jww 2014/11/06 21:28:56 Done.
Garrett Casto 2014/11/23 07:49:48 Can you add a test so that this would have been ca
jww 2014/11/25 02:46:25 Yup, unit tests are my next step.
445 if (ShouldFillOnAccountSelect()) {
446 username_element.setAutofilled(true);
447 return false;
448 } else if (username_element.value().isEmpty()) {
449 // TODO(tkent): Check maxlength and pattern.
450 username_element.setValue(fill_data.basic_data.fields[0].value, true);
451 }
452 } else if (ShouldFillOnAccountSelect()) {
453 password_element.setAutofilled(true);
454 return false;
412 } 455 }
413 456
414 // Fill if we have an exact match for the username. Note that this sets 457 // Fill if we have an exact match for the username. Note that this sets
415 // username to autofilled. 458 // username to autofilled.
416 return FillUserNameAndPassword(&username_element, 459 return FillUserNameAndPassword(
417 &password_element, 460 &username_element, &password_element, fill_data,
418 fill_data, 461 EXACT_USERNAME_MATCH | FILL_PREFERRED_USERNAME, registration_callback);
419 true /* exact_username_match */,
420 false /* set_selection */,
421 registration_callback);
422 } 462 }
423 463
424 // Takes a |map| with pointers as keys and linked_ptr as values, and returns 464 // Takes a |map| with pointers as keys and linked_ptr as values, and returns
425 // true if |key| is not NULL and |map| contains a non-NULL entry for |key|. 465 // true if |key| is not NULL and |map| contains a non-NULL entry for |key|.
426 // Makes sure not to create an entry as a side effect of using the operator []. 466 // Makes sure not to create an entry as a side effect of using the operator [].
427 template <class Key, class Value> 467 template <class Key, class Value>
428 bool ContainsNonNullEntryForNonNullKey( 468 bool ContainsNonNullEntryForNonNullKey(
429 const std::map<Key*, linked_ptr<Value>>& map, 469 const std::map<Key*, linked_ptr<Value>>& map,
430 Key* key) { 470 Key* key) {
431 if (!key) 471 if (!key)
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 553
514 blink::WebInputElement password = password_info.password_field; 554 blink::WebInputElement password = password_info.password_field;
515 if (!IsElementEditable(password)) 555 if (!IsElementEditable(password))
516 return false; 556 return false;
517 557
518 blink::WebInputElement username = element; // We need a non-const. 558 blink::WebInputElement username = element; // We need a non-const.
519 559
520 // Do not set selection when ending an editing session, otherwise it can 560 // Do not set selection when ending an editing session, otherwise it can
521 // mess with focus. 561 // mess with focus.
522 if (FillUserNameAndPassword( 562 if (FillUserNameAndPassword(
523 &username, 563 &username, &password, fill_data, EXACT_USERNAME_MATCH,
524 &password,
525 fill_data,
526 true /* exact_username_match */,
527 false /* set_selection */,
528 base::Bind(&PasswordValueGatekeeper::RegisterElement, 564 base::Bind(&PasswordValueGatekeeper::RegisterElement,
529 base::Unretained(&gatekeeper_)))) { 565 base::Unretained(&gatekeeper_)))) {
530 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED; 566 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED;
531 } 567 }
532 return true; 568 return true;
533 } 569 }
534 570
535 bool PasswordAutofillAgent::TextDidChangeInTextField( 571 bool PasswordAutofillAgent::TextDidChangeInTextField(
536 const blink::WebInputElement& element) { 572 const blink::WebInputElement& element) {
537 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 573 // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 const blink::WebNode& node) { 713 const blink::WebNode& node) {
678 blink::WebInputElement username_element; 714 blink::WebInputElement username_element;
679 PasswordInfo* password_info; 715 PasswordInfo* password_info;
680 if (!FindLoginInfo(node, &username_element, &password_info)) 716 if (!FindLoginInfo(node, &username_element, &password_info))
681 return false; 717 return false;
682 718
683 ClearPreview(&username_element, &password_info->password_field); 719 ClearPreview(&username_element, &password_info->password_field);
684 return true; 720 return true;
685 } 721 }
686 722
723 PasswordAutofillAgent::LoginToPasswordInfoMap::iterator
724 PasswordAutofillAgent::FindPasswordInfoForElement(
725 const blink::WebInputElement& element) {
726 const blink::WebInputElement* username_element;
Garrett Casto 2014/11/04 23:35:30 Why does this need to be a pointer?
jww 2014/11/06 21:28:56 I was trying to have only return statement, and si
727 if (!element.isPasswordField()) {
728 username_element = &element;
729 } else {
730 PasswordToLoginMap::const_iterator password_iter =
731 password_to_username_.find(element);
Garrett Casto 2014/11/04 23:35:30 Where is this defined and populated?
jww 2014/11/06 21:28:57 It's defined in password_autofill_agent.h and it i
732 if (password_iter == password_to_username_.end())
733 return login_to_password_info_.end();
734 username_element = &password_iter->second;
735 }
736
737 return login_to_password_info_.find(*username_element);
738 }
739
687 bool PasswordAutofillAgent::ShowSuggestions( 740 bool PasswordAutofillAgent::ShowSuggestions(
688 const blink::WebInputElement& element, 741 const blink::WebInputElement& element,
689 bool show_all) { 742 bool show_all) {
690 LoginToPasswordInfoMap::const_iterator iter = 743 LoginToPasswordInfoMap::const_iterator iter =
691 login_to_password_info_.find(element); 744 FindPasswordInfoForElement(element);
692 if (iter == login_to_password_info_.end()) 745 if (iter == login_to_password_info_.end())
693 return false; 746 return false;
694 747
695 // If autocomplete='off' is set on the form elements, no suggestion dialog 748 // If autocomplete='off' is set on the form elements, no suggestion dialog
696 // should be shown. However, return |true| to indicate that this is a known 749 // should be shown. However, return |true| to indicate that this is a known
697 // password form and that the request to show suggestions has been handled (as 750 // password form and that the request to show suggestions has been handled (as
698 // a no-op). 751 // a no-op).
699 if (!IsElementAutocompletable(element) || 752 if (!IsElementAutocompletable(element) ||
700 !IsElementAutocompletable(iter->second.password_field)) 753 !IsElementAutocompletable(iter->second.password_field))
701 return true; 754 return true;
702 755
703 return ShowSuggestionPopup(iter->second.fill_data, element, show_all); 756 // Chrome should never show more than one account for a password element since
757 // this implies that the username element cannot be modified. Thus even if
758 // |show_all| is true, check if the element in question is a password element
759 // for the call to ShowSuggestionPopup.
760 return ShowSuggestionPopup(iter->second.fill_data, iter->first,
761 show_all && !element.isPasswordField(),
762 element.isPasswordField());
Garrett Casto 2014/11/04 23:35:30 Is there any reason why you need the fourth parame
jww 2014/11/06 21:28:57 Yes, because we ultimately need the username as th
Garrett Casto 2014/11/23 07:49:48 I'm not sure that I understand why we need the use
jww 2014/11/25 02:46:25 I believe it's because the browser process can onl
704 } 763 }
705 764
706 bool PasswordAutofillAgent::OriginCanAccessPasswordManager( 765 bool PasswordAutofillAgent::OriginCanAccessPasswordManager(
707 const blink::WebSecurityOrigin& origin) { 766 const blink::WebSecurityOrigin& origin) {
708 return origin.canAccessPasswordManager(); 767 return origin.canAccessPasswordManager();
709 } 768 }
710 769
711 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) { 770 void PasswordAutofillAgent::OnDynamicFormsSeen(blink::WebFrame* frame) {
712 SendPasswordForms(frame, false /* only_visible */); 771 SendPasswordForms(frame, false /* only_visible */);
713 } 772 }
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1042 break; 1101 break;
1043 1102
1044 // Get pointer to password element. (We currently only support single 1103 // Get pointer to password element. (We currently only support single
1045 // password forms). 1104 // password forms).
1046 password_element = 1105 password_element =
1047 form_elements->input_elements[form_data.basic_data.fields[1].name]; 1106 form_elements->input_elements[form_data.basic_data.fields[1].name];
1048 1107
1049 // If wait_for_username is true, we don't want to initially fill the form 1108 // If wait_for_username is true, we don't want to initially fill the form
1050 // until the user types in a valid username. 1109 // until the user types in a valid username.
1051 if (!form_data.wait_for_username && 1110 if (!form_data.wait_for_username &&
1052 FillFormOnPasswordRecieved( 1111 FillFormOnPasswordReceived(
1053 form_data, 1112 form_data, username_element, password_element,
1054 username_element,
1055 password_element,
1056 base::Bind(&PasswordValueGatekeeper::RegisterElement, 1113 base::Bind(&PasswordValueGatekeeper::RegisterElement,
1057 base::Unretained(&gatekeeper_)))) { 1114 base::Unretained(&gatekeeper_)))) {
1058 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED; 1115 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED;
1059 } 1116 }
1060 // We might have already filled this form if there are two <form> elements 1117 // We might have already filled this form if there are two <form> elements
1061 // with identical markup. 1118 // with identical markup.
1062 if (login_to_password_info_.find(username_element) != 1119 if (login_to_password_info_.find(username_element) !=
1063 login_to_password_info_.end()) 1120 login_to_password_info_.end())
1064 continue; 1121 continue;
1065 1122
(...skipping 22 matching lines...) Expand all
1088 //////////////////////////////////////////////////////////////////////////////// 1145 ////////////////////////////////////////////////////////////////////////////////
1089 // PasswordAutofillAgent, private: 1146 // PasswordAutofillAgent, private:
1090 1147
1091 PasswordAutofillAgent::PasswordInfo::PasswordInfo() 1148 PasswordAutofillAgent::PasswordInfo::PasswordInfo()
1092 : backspace_pressed_last(false), password_was_edited_last(false) { 1149 : backspace_pressed_last(false), password_was_edited_last(false) {
1093 } 1150 }
1094 1151
1095 bool PasswordAutofillAgent::ShowSuggestionPopup( 1152 bool PasswordAutofillAgent::ShowSuggestionPopup(
1096 const PasswordFormFillData& fill_data, 1153 const PasswordFormFillData& fill_data,
1097 const blink::WebInputElement& user_input, 1154 const blink::WebInputElement& user_input,
1098 bool show_all) { 1155 bool show_all,
1156 bool show_on_password_field) {
1099 blink::WebFrame* frame = user_input.document().frame(); 1157 blink::WebFrame* frame = user_input.document().frame();
1100 if (!frame) 1158 if (!frame)
1101 return false; 1159 return false;
1102 1160
1103 blink::WebView* webview = frame->view(); 1161 blink::WebView* webview = frame->view();
1104 if (!webview) 1162 if (!webview)
1105 return false; 1163 return false;
1106 1164
1107 FormData form; 1165 FormData form;
1108 FormFieldData field; 1166 FormFieldData field;
1109 FindFormAndFieldForFormControlElement( 1167 FindFormAndFieldForFormControlElement(
1110 user_input, &form, &field, REQUIRE_NONE); 1168 user_input, &form, &field, REQUIRE_NONE);
1111 1169
1112 blink::WebInputElement selected_element = user_input; 1170 blink::WebInputElement selected_element = user_input;
1171 if (show_on_password_field) {
1172 LoginToPasswordInfoMap::const_iterator iter =
1173 login_to_password_info_.find(user_input);
1174 DCHECK(iter != login_to_password_info_.end());
1175 selected_element = iter->second.password_field;
1176 }
1113 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); 1177 gfx::Rect bounding_box(selected_element.boundsInViewportSpace());
1114 1178
1115 float scale = web_view_->pageScaleFactor(); 1179 float scale = web_view_->pageScaleFactor();
1116 gfx::RectF bounding_box_scaled(bounding_box.x() * scale, 1180 gfx::RectF bounding_box_scaled(bounding_box.x() * scale,
1117 bounding_box.y() * scale, 1181 bounding_box.y() * scale,
1118 bounding_box.width() * scale, 1182 bounding_box.width() * scale,
1119 bounding_box.height() * scale); 1183 bounding_box.height() * scale);
1120 Send(new AutofillHostMsg_ShowPasswordSuggestions( 1184 if (show_on_password_field) {
1121 routing_id(), field, user_input.value(), show_all, bounding_box_scaled)); 1185 Send(new AutofillHostMsg_ShowPasswordSuggestionsForPasswordField(
1186 routing_id(), field, user_input.value(), show_all,
1187 bounding_box_scaled));
1188 } else {
1189 Send(new AutofillHostMsg_ShowPasswordSuggestions(
1190 routing_id(), field, user_input.value(), show_all,
1191 bounding_box_scaled));
1192 }
1122 1193
1123 bool suggestions_present = false; 1194 bool suggestions_present = false;
1124 if (GetSuggestionsStats(fill_data, user_input.value(), show_all, 1195 if (GetSuggestionsStats(fill_data, user_input.value(), show_all,
1125 &suggestions_present)) { 1196 &suggestions_present)) {
1126 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; 1197 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN;
1127 } 1198 }
1128 return suggestions_present; 1199 return suggestions_present;
1129 } 1200 }
1130 1201
1131 void PasswordAutofillAgent::PerformInlineAutocomplete( 1202 void PasswordAutofillAgent::PerformInlineAutocomplete(
(...skipping 13 matching lines...) Expand all
1145 return; 1216 return;
1146 } 1217 }
1147 1218
1148 // Show the popup with the list of available usernames. 1219 // Show the popup with the list of available usernames.
1149 ShowSuggestionPopup(fill_data, username, false); 1220 ShowSuggestionPopup(fill_data, username, false);
1150 1221
1151 #if !defined(OS_ANDROID) 1222 #if !defined(OS_ANDROID)
1152 // Fill the user and password field with the most relevant match. Android 1223 // Fill the user and password field with the most relevant match. Android
1153 // only fills in the fields after the user clicks on the suggestion popup. 1224 // only fills in the fields after the user clicks on the suggestion popup.
1154 if (FillUserNameAndPassword( 1225 if (FillUserNameAndPassword(
1155 &username, 1226 &username, &password, fill_data, SET_SELECTION,
1156 &password,
1157 fill_data,
1158 false /* exact_username_match */,
1159 true /* set_selection */,
1160 base::Bind(&PasswordValueGatekeeper::RegisterElement, 1227 base::Bind(&PasswordValueGatekeeper::RegisterElement,
1161 base::Unretained(&gatekeeper_)))) { 1228 base::Unretained(&gatekeeper_)))) {
1162 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED; 1229 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED;
1163 } 1230 }
1164 #endif 1231 #endif
1165 } 1232 }
1166 1233
1167 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { 1234 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) {
1168 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); 1235 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin();
1169 iter != login_to_password_info_.end();) { 1236 iter != login_to_password_info_.end();) {
(...skipping 20 matching lines...) Expand all
1190 blink::WebInputElement* found_input, 1257 blink::WebInputElement* found_input,
1191 PasswordInfo** found_password) { 1258 PasswordInfo** found_password) {
1192 if (!node.isElementNode()) 1259 if (!node.isElementNode())
1193 return false; 1260 return false;
1194 1261
1195 blink::WebElement element = node.toConst<blink::WebElement>(); 1262 blink::WebElement element = node.toConst<blink::WebElement>();
1196 if (!element.hasHTMLTagName("input")) 1263 if (!element.hasHTMLTagName("input"))
1197 return false; 1264 return false;
1198 1265
1199 blink::WebInputElement input = element.to<blink::WebInputElement>(); 1266 blink::WebInputElement input = element.to<blink::WebInputElement>();
1200 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); 1267 LoginToPasswordInfoMap::iterator iter = FindPasswordInfoForElement(input);
1201 if (iter == login_to_password_info_.end()) 1268 if (iter == login_to_password_info_.end())
1202 return false; 1269 return false;
1203 1270
1204 *found_input = input; 1271 *found_input = input;
1205 *found_password = &iter->second; 1272 *found_password = &iter->second;
1206 return true; 1273 return true;
1207 } 1274 }
1208 1275
1209 void PasswordAutofillAgent::ClearPreview( 1276 void PasswordAutofillAgent::ClearPreview(
1210 blink::WebInputElement* username, 1277 blink::WebInputElement* username,
(...skipping 25 matching lines...) Expand all
1236 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form)); 1303 scoped_ptr<PasswordForm> password_form(CreatePasswordForm(form));
1237 if (!password_form || (restriction == RESTRICTION_NON_EMPTY_PASSWORD && 1304 if (!password_form || (restriction == RESTRICTION_NON_EMPTY_PASSWORD &&
1238 password_form->password_value.empty() && 1305 password_form->password_value.empty() &&
1239 password_form->new_password_value.empty())) { 1306 password_form->new_password_value.empty())) {
1240 return; 1307 return;
1241 } 1308 }
1242 provisionally_saved_forms_[frame].reset(password_form.release()); 1309 provisionally_saved_forms_[frame].reset(password_form.release());
1243 } 1310 }
1244 1311
1245 } // namespace autofill 1312 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698