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 21 matching lines...) Expand all Loading... |
32 #include "third_party/WebKit/public/web/WebView.h" | 32 #include "third_party/WebKit/public/web/WebView.h" |
33 #include "ui/events/keycodes/keyboard_codes.h" | 33 #include "ui/events/keycodes/keyboard_codes.h" |
34 | 34 |
35 namespace autofill { | 35 namespace autofill { |
36 namespace { | 36 namespace { |
37 | 37 |
38 // The size above which we stop triggering autocomplete. | 38 // The size above which we stop triggering autocomplete. |
39 static const size_t kMaximumTextSizeForAutocomplete = 1000; | 39 static const size_t kMaximumTextSizeForAutocomplete = 1000; |
40 | 40 |
41 // Maps element names to the actual elements to simplify form filling. | 41 // Maps element names to the actual elements to simplify form filling. |
42 typedef std::map<base::string16, blink::WebInputElement> | 42 typedef std::map<base::string16, blink::WebInputElement> FormInputElementMap; |
43 FormInputElementMap; | |
44 | 43 |
45 // Utility struct for form lookup and autofill. When we parse the DOM to look up | 44 // Utility struct for form lookup and autofill. When we parse the DOM to look up |
46 // a form, in addition to action and origin URL's we have to compare all | 45 // a form, in addition to action and origin URL's we have to compare all |
47 // necessary form elements. To avoid having to look these up again when we want | 46 // necessary form elements. To avoid having to look these up again when we want |
48 // to fill the form, the FindFormElements function stores the pointers | 47 // to fill the form, the FindFormElements function stores the pointers |
49 // in a FormElements* result, referenced to ensure they are safe to use. | 48 // in a FormElements* result, referenced to ensure they are safe to use. |
50 struct FormElements { | 49 struct FormElements { |
51 blink::WebFormElement form_element; | 50 blink::WebFormElement form_element; |
52 FormInputElementMap input_elements; | 51 FormInputElementMap input_elements; |
53 }; | 52 }; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 //////////////////////////////////////////////////////////////////////////////// | 205 //////////////////////////////////////////////////////////////////////////////// |
207 // PasswordAutofillAgent, public: | 206 // PasswordAutofillAgent, public: |
208 | 207 |
209 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view) | 208 PasswordAutofillAgent::PasswordAutofillAgent(content::RenderView* render_view) |
210 : content::RenderViewObserver(render_view), | 209 : content::RenderViewObserver(render_view), |
211 usernames_usage_(NOTHING_TO_AUTOFILL), | 210 usernames_usage_(NOTHING_TO_AUTOFILL), |
212 web_view_(render_view->GetWebView()), | 211 web_view_(render_view->GetWebView()), |
213 weak_ptr_factory_(this) { | 212 weak_ptr_factory_(this) { |
214 } | 213 } |
215 | 214 |
216 PasswordAutofillAgent::~PasswordAutofillAgent() {} | 215 PasswordAutofillAgent::~PasswordAutofillAgent() { |
| 216 } |
217 | 217 |
218 PasswordAutofillAgent::PasswordValueGatekeeper::PasswordValueGatekeeper() | 218 PasswordAutofillAgent::PasswordValueGatekeeper::PasswordValueGatekeeper() |
219 : was_user_gesture_seen_(false) {} | 219 : was_user_gesture_seen_(false) { |
| 220 } |
220 | 221 |
221 PasswordAutofillAgent::PasswordValueGatekeeper::~PasswordValueGatekeeper() {} | 222 PasswordAutofillAgent::PasswordValueGatekeeper::~PasswordValueGatekeeper() { |
| 223 } |
222 | 224 |
223 void PasswordAutofillAgent::PasswordValueGatekeeper::RegisterElement( | 225 void PasswordAutofillAgent::PasswordValueGatekeeper::RegisterElement( |
224 blink::WebInputElement* element) { | 226 blink::WebInputElement* element) { |
225 if (was_user_gesture_seen_) | 227 if (was_user_gesture_seen_) |
226 ShowValue(element); | 228 ShowValue(element); |
227 else | 229 else |
228 elements_.push_back(*element); | 230 elements_.push_back(*element); |
229 } | 231 } |
230 | 232 |
231 void PasswordAutofillAgent::PasswordValueGatekeeper::OnUserGesture() { | 233 void PasswordAutofillAgent::PasswordValueGatekeeper::OnUserGesture() { |
(...skipping 19 matching lines...) Expand all Loading... |
251 element->setValue(element->suggestedValue(), true); | 253 element->setValue(element->suggestedValue(), true); |
252 } | 254 } |
253 | 255 |
254 bool PasswordAutofillAgent::TextFieldDidEndEditing( | 256 bool PasswordAutofillAgent::TextFieldDidEndEditing( |
255 const blink::WebInputElement& element) { | 257 const blink::WebInputElement& element) { |
256 LoginToPasswordInfoMap::const_iterator iter = | 258 LoginToPasswordInfoMap::const_iterator iter = |
257 login_to_password_info_.find(element); | 259 login_to_password_info_.find(element); |
258 if (iter == login_to_password_info_.end()) | 260 if (iter == login_to_password_info_.end()) |
259 return false; | 261 return false; |
260 | 262 |
261 const PasswordFormFillData& fill_data = | 263 const PasswordFormFillData& fill_data = iter->second.fill_data; |
262 iter->second.fill_data; | |
263 | 264 |
264 // If wait_for_username is false, we should have filled when the text changed. | 265 // If wait_for_username is false, we should have filled when the text changed. |
265 if (!fill_data.wait_for_username) | 266 if (!fill_data.wait_for_username) |
266 return false; | 267 return false; |
267 | 268 |
268 blink::WebInputElement password = iter->second.password_field; | 269 blink::WebInputElement password = iter->second.password_field; |
269 if (!IsElementEditable(password)) | 270 if (!IsElementEditable(password)) |
270 return false; | 271 return false; |
271 | 272 |
272 blink::WebInputElement username = element; // We need a non-const. | 273 blink::WebInputElement username = element; // We need a non-const. |
273 | 274 |
274 // Do not set selection when ending an editing session, otherwise it can | 275 // Do not set selection when ending an editing session, otherwise it can |
275 // mess with focus. | 276 // mess with focus. |
276 FillUserNameAndPassword(&username, &password, fill_data, | 277 FillUserNameAndPassword(&username, |
| 278 &password, |
| 279 fill_data, |
277 true /* exact_username_match */, | 280 true /* exact_username_match */, |
278 false /* set_selection */); | 281 false /* set_selection */); |
279 return true; | 282 return true; |
280 } | 283 } |
281 | 284 |
282 bool PasswordAutofillAgent::TextDidChangeInTextField( | 285 bool PasswordAutofillAgent::TextDidChangeInTextField( |
283 const blink::WebInputElement& element) { | 286 const blink::WebInputElement& element) { |
284 LoginToPasswordInfoMap::const_iterator iter = | 287 LoginToPasswordInfoMap::const_iterator iter = |
285 login_to_password_info_.find(element); | 288 login_to_password_info_.find(element); |
286 if (iter == login_to_password_info_.end()) | 289 if (iter == login_to_password_info_.end()) |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 IPC_BEGIN_MESSAGE_MAP(PasswordAutofillAgent, message) | 458 IPC_BEGIN_MESSAGE_MAP(PasswordAutofillAgent, message) |
456 IPC_MESSAGE_HANDLER(AutofillMsg_FillPasswordForm, OnFillPasswordForm) | 459 IPC_MESSAGE_HANDLER(AutofillMsg_FillPasswordForm, OnFillPasswordForm) |
457 IPC_MESSAGE_UNHANDLED(handled = false) | 460 IPC_MESSAGE_UNHANDLED(handled = false) |
458 IPC_END_MESSAGE_MAP() | 461 IPC_END_MESSAGE_MAP() |
459 return handled; | 462 return handled; |
460 } | 463 } |
461 | 464 |
462 void PasswordAutofillAgent::DidStartLoading() { | 465 void PasswordAutofillAgent::DidStartLoading() { |
463 if (usernames_usage_ != NOTHING_TO_AUTOFILL) { | 466 if (usernames_usage_ != NOTHING_TO_AUTOFILL) { |
464 UMA_HISTOGRAM_ENUMERATION("PasswordManager.OtherPossibleUsernamesUsage", | 467 UMA_HISTOGRAM_ENUMERATION("PasswordManager.OtherPossibleUsernamesUsage", |
465 usernames_usage_, OTHER_POSSIBLE_USERNAMES_MAX); | 468 usernames_usage_, |
| 469 OTHER_POSSIBLE_USERNAMES_MAX); |
466 usernames_usage_ = NOTHING_TO_AUTOFILL; | 470 usernames_usage_ = NOTHING_TO_AUTOFILL; |
467 } | 471 } |
468 } | 472 } |
469 | 473 |
470 void PasswordAutofillAgent::DidFinishDocumentLoad(blink::WebLocalFrame* frame) { | 474 void PasswordAutofillAgent::DidFinishDocumentLoad(blink::WebLocalFrame* frame) { |
471 // The |frame| contents have been parsed, but not yet rendered. Let the | 475 // The |frame| contents have been parsed, but not yet rendered. Let the |
472 // PasswordManager know that forms are loaded, even though we can't yet tell | 476 // PasswordManager know that forms are loaded, even though we can't yet tell |
473 // whether they're visible. | 477 // whether they're visible. |
474 SendPasswordForms(frame, false); | 478 SendPasswordForms(frame, false); |
475 } | 479 } |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 // If the navigation is not triggered by a user gesture, e.g. by some ajax | 560 // If the navigation is not triggered by a user gesture, e.g. by some ajax |
557 // callback, then inherit the submitted password form from the previous | 561 // callback, then inherit the submitted password form from the previous |
558 // state. This fixes the no password save issue for ajax login, tracked in | 562 // state. This fixes the no password save issue for ajax login, tracked in |
559 // [http://crbug/43219]. Note that this still fails for sites that use | 563 // [http://crbug/43219]. Note that this still fails for sites that use |
560 // synchonous XHR as isProcessingUserGesture() will return true. | 564 // synchonous XHR as isProcessingUserGesture() will return true. |
561 blink::WebFrame* form_frame = CurrentOrChildFrameWithSavedForms(frame); | 565 blink::WebFrame* form_frame = CurrentOrChildFrameWithSavedForms(frame); |
562 if (!blink::WebUserGestureIndicator::isProcessingUserGesture()) { | 566 if (!blink::WebUserGestureIndicator::isProcessingUserGesture()) { |
563 // If onsubmit has been called, try and save that form. | 567 // If onsubmit has been called, try and save that form. |
564 if (provisionally_saved_forms_[form_frame].get()) { | 568 if (provisionally_saved_forms_[form_frame].get()) { |
565 Send(new AutofillHostMsg_PasswordFormSubmitted( | 569 Send(new AutofillHostMsg_PasswordFormSubmitted( |
566 routing_id(), | 570 routing_id(), *provisionally_saved_forms_[form_frame])); |
567 *provisionally_saved_forms_[form_frame])); | |
568 provisionally_saved_forms_.erase(form_frame); | 571 provisionally_saved_forms_.erase(form_frame); |
569 } else { | 572 } else { |
570 // Loop through the forms on the page looking for one that has been | 573 // Loop through the forms on the page looking for one that has been |
571 // filled out. If one exists, try and save the credentials. | 574 // filled out. If one exists, try and save the credentials. |
572 blink::WebVector<blink::WebFormElement> forms; | 575 blink::WebVector<blink::WebFormElement> forms; |
573 frame->document().forms(forms); | 576 frame->document().forms(forms); |
574 | 577 |
575 for (size_t i = 0; i < forms.size(); ++i) { | 578 for (size_t i = 0; i < forms.size(); ++i) { |
576 blink::WebFormElement form_element= forms[i]; | 579 blink::WebFormElement form_element = forms[i]; |
577 scoped_ptr<PasswordForm> password_form( | 580 scoped_ptr<PasswordForm> password_form( |
578 CreatePasswordForm(form_element)); | 581 CreatePasswordForm(form_element)); |
579 if (password_form.get() && | 582 if (password_form.get() && !password_form->username_value.empty() && |
580 !password_form->username_value.empty() && | |
581 !password_form->password_value.empty() && | 583 !password_form->password_value.empty() && |
582 !PasswordValueIsDefault(*password_form, form_element)) { | 584 !PasswordValueIsDefault(*password_form, form_element)) { |
583 Send(new AutofillHostMsg_PasswordFormSubmitted( | 585 Send(new AutofillHostMsg_PasswordFormSubmitted(routing_id(), |
584 routing_id(), *password_form)); | 586 *password_form)); |
585 } | 587 } |
586 } | 588 } |
587 } | 589 } |
588 } | 590 } |
589 // Clear the whole map during main frame navigation. | 591 // Clear the whole map during main frame navigation. |
590 provisionally_saved_forms_.clear(); | 592 provisionally_saved_forms_.clear(); |
591 | 593 |
592 // This is a new navigation, so require a new user gesture before filling in | 594 // This is a new navigation, so require a new user gesture before filling in |
593 // passwords. | 595 // passwords. |
594 gatekeeper_.Reset(); | 596 gatekeeper_.Reset(); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
635 PasswordInfo password_info; | 637 PasswordInfo password_info; |
636 password_info.fill_data = form_data; | 638 password_info.fill_data = form_data; |
637 password_info.password_field = password_element; | 639 password_info.password_field = password_element; |
638 login_to_password_info_[username_element] = password_info; | 640 login_to_password_info_[username_element] = password_info; |
639 | 641 |
640 FormData form; | 642 FormData form; |
641 FormFieldData field; | 643 FormFieldData field; |
642 FindFormAndFieldForFormControlElement( | 644 FindFormAndFieldForFormControlElement( |
643 username_element, &form, &field, REQUIRE_NONE); | 645 username_element, &form, &field, REQUIRE_NONE); |
644 Send(new AutofillHostMsg_AddPasswordFormMapping( | 646 Send(new AutofillHostMsg_AddPasswordFormMapping( |
645 routing_id(), | 647 routing_id(), field, form_data)); |
646 field, | |
647 form_data)); | |
648 } | 648 } |
649 } | 649 } |
650 | 650 |
651 //////////////////////////////////////////////////////////////////////////////// | 651 //////////////////////////////////////////////////////////////////////////////// |
652 // PasswordAutofillAgent, private: | 652 // PasswordAutofillAgent, private: |
653 | 653 |
654 void PasswordAutofillAgent::GetSuggestions( | 654 void PasswordAutofillAgent::GetSuggestions( |
655 const PasswordFormFillData& fill_data, | 655 const PasswordFormFillData& fill_data, |
656 const base::string16& input, | 656 const base::string16& input, |
657 std::vector<base::string16>* suggestions, | 657 std::vector<base::string16>* suggestions, |
658 std::vector<base::string16>* realms) { | 658 std::vector<base::string16>* realms) { |
659 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) { | 659 if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) { |
660 suggestions->push_back(fill_data.basic_data.fields[0].value); | 660 suggestions->push_back(fill_data.basic_data.fields[0].value); |
661 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); | 661 realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm)); |
662 } | 662 } |
663 | 663 |
664 for (PasswordFormFillData::LoginCollection::const_iterator iter = | 664 for (PasswordFormFillData::LoginCollection::const_iterator iter = |
665 fill_data.additional_logins.begin(); | 665 fill_data.additional_logins.begin(); |
666 iter != fill_data.additional_logins.end(); ++iter) { | 666 iter != fill_data.additional_logins.end(); |
| 667 ++iter) { |
667 if (StartsWith(iter->first, input, false)) { | 668 if (StartsWith(iter->first, input, false)) { |
668 suggestions->push_back(iter->first); | 669 suggestions->push_back(iter->first); |
669 realms->push_back(base::UTF8ToUTF16(iter->second.realm)); | 670 realms->push_back(base::UTF8ToUTF16(iter->second.realm)); |
670 } | 671 } |
671 } | 672 } |
672 | 673 |
673 for (PasswordFormFillData::UsernamesCollection::const_iterator iter = | 674 for (PasswordFormFillData::UsernamesCollection::const_iterator iter = |
674 fill_data.other_possible_usernames.begin(); | 675 fill_data.other_possible_usernames.begin(); |
675 iter != fill_data.other_possible_usernames.end(); ++iter) { | 676 iter != fill_data.other_possible_usernames.end(); |
| 677 ++iter) { |
676 for (size_t i = 0; i < iter->second.size(); ++i) { | 678 for (size_t i = 0; i < iter->second.size(); ++i) { |
677 if (StartsWith(iter->second[i], input, false)) { | 679 if (StartsWith(iter->second[i], input, false)) { |
678 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; | 680 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN; |
679 suggestions->push_back(iter->second[i]); | 681 suggestions->push_back(iter->second[i]); |
680 realms->push_back(base::UTF8ToUTF16(iter->first.realm)); | 682 realms->push_back(base::UTF8ToUTF16(iter->first.realm)); |
681 } | 683 } |
682 } | 684 } |
683 } | 685 } |
684 } | 686 } |
685 | 687 |
(...skipping 19 matching lines...) Expand all Loading... |
705 user_input, &form, &field, REQUIRE_NONE); | 707 user_input, &form, &field, REQUIRE_NONE); |
706 | 708 |
707 blink::WebInputElement selected_element = user_input; | 709 blink::WebInputElement selected_element = user_input; |
708 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); | 710 gfx::Rect bounding_box(selected_element.boundsInViewportSpace()); |
709 | 711 |
710 float scale = web_view_->pageScaleFactor(); | 712 float scale = web_view_->pageScaleFactor(); |
711 gfx::RectF bounding_box_scaled(bounding_box.x() * scale, | 713 gfx::RectF bounding_box_scaled(bounding_box.x() * scale, |
712 bounding_box.y() * scale, | 714 bounding_box.y() * scale, |
713 bounding_box.width() * scale, | 715 bounding_box.width() * scale, |
714 bounding_box.height() * scale); | 716 bounding_box.height() * scale); |
715 Send(new AutofillHostMsg_ShowPasswordSuggestions(routing_id(), | 717 Send(new AutofillHostMsg_ShowPasswordSuggestions( |
716 field, | 718 routing_id(), field, bounding_box_scaled, suggestions, realms)); |
717 bounding_box_scaled, | |
718 suggestions, | |
719 realms)); | |
720 return !suggestions.empty(); | 719 return !suggestions.empty(); |
721 } | 720 } |
722 | 721 |
723 void PasswordAutofillAgent::FillFormOnPasswordRecieved( | 722 void PasswordAutofillAgent::FillFormOnPasswordRecieved( |
724 const PasswordFormFillData& fill_data, | 723 const PasswordFormFillData& fill_data, |
725 blink::WebInputElement username_element, | 724 blink::WebInputElement username_element, |
726 blink::WebInputElement password_element) { | 725 blink::WebInputElement password_element) { |
727 // Do not fill if the password field is in an iframe. | 726 // Do not fill if the password field is in an iframe. |
728 DCHECK(password_element.document().frame()); | 727 DCHECK(password_element.document().frame()); |
729 if (password_element.document().frame()->parent()) | 728 if (password_element.document().frame()->parent()) |
(...skipping 10 matching lines...) Expand all Loading... |
740 // Try to set the username to the preferred name, but only if the field | 739 // Try to set the username to the preferred name, but only if the field |
741 // can be set and isn't prefilled. | 740 // can be set and isn't prefilled. |
742 if (IsElementAutocompletable(username_element) && | 741 if (IsElementAutocompletable(username_element) && |
743 username_element.value().isEmpty()) { | 742 username_element.value().isEmpty()) { |
744 // TODO(tkent): Check maxlength and pattern. | 743 // TODO(tkent): Check maxlength and pattern. |
745 username_element.setValue(fill_data.basic_data.fields[0].value, true); | 744 username_element.setValue(fill_data.basic_data.fields[0].value, true); |
746 } | 745 } |
747 | 746 |
748 // Fill if we have an exact match for the username. Note that this sets | 747 // Fill if we have an exact match for the username. Note that this sets |
749 // username to autofilled. | 748 // username to autofilled. |
750 FillUserNameAndPassword(&username_element, &password_element, fill_data, | 749 FillUserNameAndPassword(&username_element, |
| 750 &password_element, |
| 751 fill_data, |
751 true /* exact_username_match */, | 752 true /* exact_username_match */, |
752 false /* set_selection */); | 753 false /* set_selection */); |
753 } | 754 } |
754 | 755 |
755 bool PasswordAutofillAgent::FillUserNameAndPassword( | 756 bool PasswordAutofillAgent::FillUserNameAndPassword( |
756 blink::WebInputElement* username_element, | 757 blink::WebInputElement* username_element, |
757 blink::WebInputElement* password_element, | 758 blink::WebInputElement* password_element, |
758 const PasswordFormFillData& fill_data, | 759 const PasswordFormFillData& fill_data, |
759 bool exact_username_match, | 760 bool exact_username_match, |
760 bool set_selection) { | 761 bool set_selection) { |
761 base::string16 current_username = username_element->value(); | 762 base::string16 current_username = username_element->value(); |
762 // username and password will contain the match found if any. | 763 // username and password will contain the match found if any. |
763 base::string16 username; | 764 base::string16 username; |
764 base::string16 password; | 765 base::string16 password; |
765 | 766 |
766 // Look for any suitable matches to current field text. | 767 // Look for any suitable matches to current field text. |
767 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, current_username, | 768 if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, |
| 769 current_username, |
768 exact_username_match)) { | 770 exact_username_match)) { |
769 username = fill_data.basic_data.fields[0].value; | 771 username = fill_data.basic_data.fields[0].value; |
770 password = fill_data.basic_data.fields[1].value; | 772 password = fill_data.basic_data.fields[1].value; |
771 } else { | 773 } else { |
772 // Scan additional logins for a match. | 774 // Scan additional logins for a match. |
773 PasswordFormFillData::LoginCollection::const_iterator iter; | 775 PasswordFormFillData::LoginCollection::const_iterator iter; |
774 for (iter = fill_data.additional_logins.begin(); | 776 for (iter = fill_data.additional_logins.begin(); |
775 iter != fill_data.additional_logins.end(); ++iter) { | 777 iter != fill_data.additional_logins.end(); |
776 if (DoUsernamesMatch(iter->first, current_username, | 778 ++iter) { |
777 exact_username_match)) { | 779 if (DoUsernamesMatch( |
| 780 iter->first, current_username, exact_username_match)) { |
778 username = iter->first; | 781 username = iter->first; |
779 password = iter->second.password; | 782 password = iter->second.password; |
780 break; | 783 break; |
781 } | 784 } |
782 } | 785 } |
783 | 786 |
784 // Check possible usernames. | 787 // Check possible usernames. |
785 if (username.empty() && password.empty()) { | 788 if (username.empty() && password.empty()) { |
786 for (PasswordFormFillData::UsernamesCollection::const_iterator iter = | 789 for (PasswordFormFillData::UsernamesCollection::const_iterator iter = |
787 fill_data.other_possible_usernames.begin(); | 790 fill_data.other_possible_usernames.begin(); |
788 iter != fill_data.other_possible_usernames.end(); ++iter) { | 791 iter != fill_data.other_possible_usernames.end(); |
| 792 ++iter) { |
789 for (size_t i = 0; i < iter->second.size(); ++i) { | 793 for (size_t i = 0; i < iter->second.size(); ++i) { |
790 if (DoUsernamesMatch(iter->second[i], current_username, | 794 if (DoUsernamesMatch( |
791 exact_username_match)) { | 795 iter->second[i], current_username, exact_username_match)) { |
792 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED; | 796 usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED; |
793 username = iter->second[i]; | 797 username = iter->second[i]; |
794 password = iter->first.password; | 798 password = iter->first.password; |
795 break; | 799 break; |
796 } | 800 } |
797 } | 801 } |
798 if (!username.empty() && !password.empty()) | 802 if (!username.empty() && !password.empty()) |
799 break; | 803 break; |
800 } | 804 } |
801 } | 805 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 // Don't inline autocomplete if the caret is not at the end. | 853 // Don't inline autocomplete if the caret is not at the end. |
850 // TODO(jcivelli): is there a better way to test the caret location? | 854 // TODO(jcivelli): is there a better way to test the caret location? |
851 if (username.selectionStart() != username.selectionEnd() || | 855 if (username.selectionStart() != username.selectionEnd() || |
852 username.selectionEnd() != static_cast<int>(username.value().length())) { | 856 username.selectionEnd() != static_cast<int>(username.value().length())) { |
853 return; | 857 return; |
854 } | 858 } |
855 | 859 |
856 // Show the popup with the list of available usernames. | 860 // Show the popup with the list of available usernames. |
857 ShowSuggestionPopup(fill_data, username); | 861 ShowSuggestionPopup(fill_data, username); |
858 | 862 |
859 | |
860 #if !defined(OS_ANDROID) | 863 #if !defined(OS_ANDROID) |
861 // Fill the user and password field with the most relevant match. Android | 864 // Fill the user and password field with the most relevant match. Android |
862 // only fills in the fields after the user clicks on the suggestion popup. | 865 // only fills in the fields after the user clicks on the suggestion popup. |
863 FillUserNameAndPassword(&username, &password, fill_data, | 866 FillUserNameAndPassword(&username, |
| 867 &password, |
| 868 fill_data, |
864 false /* exact_username_match */, | 869 false /* exact_username_match */, |
865 true /* set_selection */); | 870 true /* set_selection */); |
866 #endif | 871 #endif |
867 } | 872 } |
868 | 873 |
869 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { | 874 void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { |
870 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); | 875 for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
871 iter != login_to_password_info_.end();) { | 876 iter != login_to_password_info_.end();) { |
872 if (iter->first.document().frame() == frame) | 877 if (iter->first.document().frame() == frame) |
873 login_to_password_info_.erase(iter++); | 878 login_to_password_info_.erase(iter++); |
(...skipping 24 matching lines...) Expand all Loading... |
898 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); | 903 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); |
899 if (iter == login_to_password_info_.end()) | 904 if (iter == login_to_password_info_.end()) |
900 return false; | 905 return false; |
901 | 906 |
902 *found_input = input; | 907 *found_input = input; |
903 *found_password = iter->second; | 908 *found_password = iter->second; |
904 return true; | 909 return true; |
905 } | 910 } |
906 | 911 |
907 } // namespace autofill | 912 } // namespace autofill |
OLD | NEW |