Chromium Code Reviews| 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 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 159 curr_elements->form_element = fe; | 159 curr_elements->form_element = fe; |
| 160 results->push_back(curr_elements.release()); | 160 results->push_back(curr_elements.release()); |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 } | 163 } |
| 164 | 164 |
| 165 bool IsElementEditable(const blink::WebInputElement& element) { | 165 bool IsElementEditable(const blink::WebInputElement& element) { |
| 166 return element.isEnabled() && !element.isReadOnly(); | 166 return element.isEnabled() && !element.isReadOnly(); |
| 167 } | 167 } |
| 168 | 168 |
| 169 void SetElementAutofilled(blink::WebInputElement* element, bool autofilled) { | |
| 170 if (element->isAutofilled() == autofilled) | |
| 171 return; | |
| 172 element->setAutofilled(autofilled); | |
| 173 // Notify any changeEvent listeners. | |
| 174 element->dispatchFormControlChangeEvent(); | |
| 175 } | |
|
Ilya Sherman
2014/03/29 00:07:07
Why is this function safe to remove? Does setAuto
Dan Beam
2014/03/29 00:51:14
no, passing true to setValue() dispatches a change
| |
| 176 | |
| 177 bool DoUsernamesMatch(const base::string16& username1, | 169 bool DoUsernamesMatch(const base::string16& username1, |
| 178 const base::string16& username2, | 170 const base::string16& username2, |
| 179 bool exact_match) { | 171 bool exact_match) { |
| 180 if (exact_match) | 172 if (exact_match) |
| 181 return username1 == username2; | 173 return username1 == username2; |
| 182 return StartsWith(username1, username2, true); | 174 return StartsWith(username1, username2, true); |
| 183 } | 175 } |
| 184 | 176 |
| 185 // Returns |true| if the given element is both editable and has permission to be | 177 // Returns |true| if the given element is both editable and has permission to be |
| 186 // autocompleted. The latter can be either because there is no | 178 // autocompleted. The latter can be either because there is no |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 288 } | 280 } |
| 289 | 281 |
| 290 bool PasswordAutofillAgent::TextDidChangeInTextField( | 282 bool PasswordAutofillAgent::TextDidChangeInTextField( |
| 291 const blink::WebInputElement& element) { | 283 const blink::WebInputElement& element) { |
| 292 LoginToPasswordInfoMap::const_iterator iter = | 284 LoginToPasswordInfoMap::const_iterator iter = |
| 293 login_to_password_info_.find(element); | 285 login_to_password_info_.find(element); |
| 294 if (iter == login_to_password_info_.end()) | 286 if (iter == login_to_password_info_.end()) |
| 295 return false; | 287 return false; |
| 296 | 288 |
| 297 // The input text is being changed, so any autofilled password is now | 289 // The input text is being changed, so any autofilled password is now |
| 298 // outdated. | 290 // outdated. |
|
Dan Beam
2014/03/29 00:51:14
^ there should already be a change dispatched in t
| |
| 299 blink::WebInputElement username = element; // We need a non-const. | 291 blink::WebInputElement username = element; // We need a non-const. |
| 292 username.setAutofilled(false); | |
| 293 | |
| 300 blink::WebInputElement password = iter->second.password_field; | 294 blink::WebInputElement password = iter->second.password_field; |
| 301 SetElementAutofilled(&username, false); | |
| 302 if (password.isAutofilled()) { | 295 if (password.isAutofilled()) { |
| 303 password.setValue(base::string16()); | 296 password.setValue(base::string16(), true); |
|
Dan Beam
2014/03/29 00:51:14
sends change ^ (when appropriate)
| |
| 304 SetElementAutofilled(&password, false); | 297 password.setAutofilled(false); |
| 305 } | 298 } |
| 306 | 299 |
| 307 // If wait_for_username is true we will fill when the username loses focus. | 300 // If wait_for_username is true we will fill when the username loses focus. |
| 308 if (iter->second.fill_data.wait_for_username) | 301 if (iter->second.fill_data.wait_for_username) |
| 309 return false; | 302 return false; |
| 310 | 303 |
| 311 if (!element.isText() || !IsElementAutocompletable(element) || | 304 if (!element.isText() || !IsElementAutocompletable(element) || |
| 312 !IsElementAutocompletable(password)) { | 305 !IsElementAutocompletable(password)) { |
| 313 return false; | 306 return false; |
| 314 } | 307 } |
| (...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 805 // fields. | 798 // fields. |
| 806 | 799 |
| 807 // Don't fill username if password can't be set. | 800 // Don't fill username if password can't be set. |
| 808 if (!IsElementAutocompletable(*password_element)) { | 801 if (!IsElementAutocompletable(*password_element)) { |
| 809 return false; | 802 return false; |
| 810 } | 803 } |
| 811 | 804 |
| 812 // Input matches the username, fill in required values. | 805 // Input matches the username, fill in required values. |
| 813 if (IsElementAutocompletable(*username_element)) { | 806 if (IsElementAutocompletable(*username_element)) { |
| 814 username_element->setValue(username, true); | 807 username_element->setValue(username, true); |
| 815 SetElementAutofilled(username_element, true); | 808 username_element->setAutofilled(true); |
|
Dan Beam
2014/03/29 00:51:14
^ this previously could've attempted to send 2 cha
| |
| 816 | 809 |
| 817 if (set_selection) { | 810 if (set_selection) { |
| 818 username_element->setSelectionRange(current_username.length(), | 811 username_element->setSelectionRange(current_username.length(), |
| 819 username.length()); | 812 username.length()); |
| 820 } | 813 } |
| 821 } else if (current_username != username) { | 814 } else if (current_username != username) { |
| 822 // If the username can't be filled and it doesn't match a saved password | 815 // If the username can't be filled and it doesn't match a saved password |
| 823 // as is, don't autofill a password. | 816 // as is, don't autofill a password. |
| 824 return false; | 817 return false; |
| 825 } | 818 } |
| 826 | 819 |
| 827 // TODO(vabr): The "gatekeeper" feature is currently disabled on mobile. | 820 // TODO(vabr): The "gatekeeper" feature is currently disabled on mobile. |
| 828 // http://crbug.com/345510#c13 | 821 // http://crbug.com/345510#c13 |
| 829 #if !defined(OS_ANDROID) || !defined(OS_IOS) | 822 #if !defined(OS_ANDROID) || !defined(OS_IOS) |
| 830 // Wait to fill in the password until a user gesture occurs. This is to make | 823 // Wait to fill in the password until a user gesture occurs. This is to make |
| 831 // sure that we do not fill in the DOM with a password until we believe the | 824 // sure that we do not fill in the DOM with a password until we believe the |
| 832 // user is intentionally interacting with the page. | 825 // user is intentionally interacting with the page. |
| 833 password_element->setSuggestedValue(password); | 826 password_element->setSuggestedValue(password); |
| 834 gatekeeper_.RegisterElement(password_element); | 827 gatekeeper_.RegisterElement(password_element); |
| 835 #else | 828 #else |
| 836 password_element->setValue(password); | 829 password_element->setValue(password); |
| 837 #endif | 830 #endif |
| 838 | 831 |
| 839 // Note: Don't call SetElementAutofilled() here, as that dispatches an | |
| 840 // onChange event in JavaScript, which is not appropriate for the password | |
| 841 // element if a user gesture has not yet occured. | |
|
Ilya Sherman
2014/03/29 00:07:07
How is this case handled now? We shouldn't trigge
Dan Beam
2014/03/29 00:51:14
setAutofilled() doesn't dispatch a change
| |
| 842 password_element->setAutofilled(true); | 832 password_element->setAutofilled(true); |
| 843 return true; | 833 return true; |
| 844 } | 834 } |
| 845 | 835 |
| 846 void PasswordAutofillAgent::PerformInlineAutocomplete( | 836 void PasswordAutofillAgent::PerformInlineAutocomplete( |
| 847 const blink::WebInputElement& username_input, | 837 const blink::WebInputElement& username_input, |
| 848 const blink::WebInputElement& password_input, | 838 const blink::WebInputElement& password_input, |
| 849 const PasswordFormFillData& fill_data) { | 839 const PasswordFormFillData& fill_data) { |
| 850 DCHECK(!fill_data.wait_for_username); | 840 DCHECK(!fill_data.wait_for_username); |
| 851 | 841 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 905 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); | 895 LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(input); |
| 906 if (iter == login_to_password_info_.end()) | 896 if (iter == login_to_password_info_.end()) |
| 907 return false; | 897 return false; |
| 908 | 898 |
| 909 *found_input = input; | 899 *found_input = input; |
| 910 *found_password = iter->second; | 900 *found_password = iter->second; |
| 911 return true; | 901 return true; |
| 912 } | 902 } |
| 913 | 903 |
| 914 } // namespace autofill | 904 } // namespace autofill |
| OLD | NEW |