Chromium Code Reviews| Index: components/autofill/content/renderer/password_autofill_agent.cc |
| diff --git a/components/autofill/content/renderer/password_autofill_agent.cc b/components/autofill/content/renderer/password_autofill_agent.cc |
| index 629627dc4205c6821b3a4637909608aace03a82c..a1c2291a90efc91bd6ca4020e21564d791385206 100644 |
| --- a/components/autofill/content/renderer/password_autofill_agent.cc |
| +++ b/components/autofill/content/renderer/password_autofill_agent.cc |
| @@ -273,8 +273,11 @@ void PasswordAutofillAgent::PasswordValueGatekeeper::Reset() { |
| void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue( |
| blink::WebInputElement* element) { |
| - if (!element->isNull() && !element->suggestedValue().isNull()) |
| + if (!element->isNull() && element->value().isNull() && |
|
engedy
2014/07/29 17:47:56
Could you please double-check that we first erase
vabr (Chromium)
2014/07/30 16:46:58
Great catch. Indeed, I broke this. It should be no
|
| + !element->suggestedValue().isNull()) { |
| element->setValue(element->suggestedValue(), true); |
| + element->setSuggestedValue(blink::WebString()); |
|
vabr (Chromium)
2014/07/30 16:46:58
I just discovered that setValue clears the suggest
|
| + } |
| } |
| bool PasswordAutofillAgent::TextFieldDidEndEditing( |
| @@ -296,6 +299,10 @@ bool PasswordAutofillAgent::TextFieldDidEndEditing( |
| blink::WebInputElement username = element; // We need a non-const. |
| + // Don't let autofill overwrite an explicit change made by the user. |
| + if (iter->second.user_changed_password_more_recently_than_username) |
|
engedy
2014/07/29 17:47:56
I have put some more though into this, I *think* t
vabr (Chromium)
2014/07/30 16:46:59
Your semantics sounds reasonable to me. I tried to
|
| + return false; |
| + |
| // Do not set selection when ending an editing session, otherwise it can |
| // mess with focus. |
| FillUserNameAndPassword(&username, |
| @@ -308,6 +315,19 @@ bool PasswordAutofillAgent::TextFieldDidEndEditing( |
| bool PasswordAutofillAgent::TextDidChangeInTextField( |
| const blink::WebInputElement& element) { |
| + // TODO(vabr): Get a mutable argument instead. http://crbug.com/397083 |
| + blink::WebInputElement mutable_element = element; // We need a non-const. |
| + |
| + if (element.isPasswordField()) { |
| + PasswordToLoginMap::iterator iter = password_to_username_.find(element); |
| + if (iter != password_to_username_.end()) { |
| + login_to_password_info_[iter->second] |
| + .user_changed_password_more_recently_than_username = true; |
| + mutable_element.setAutofilled(false); |
| + } |
| + return false; |
| + } |
| + |
| LoginToPasswordInfoMap::const_iterator iter = |
| login_to_password_info_.find(element); |
| if (iter == login_to_password_info_.end()) |
| @@ -315,8 +335,9 @@ bool PasswordAutofillAgent::TextDidChangeInTextField( |
| // The input text is being changed, so any autofilled password is now |
| // outdated. |
| - blink::WebInputElement username = element; // We need a non-const. |
| - username.setAutofilled(false); |
| + mutable_element.setAutofilled(false); |
| + login_to_password_info_[element] |
| + .user_changed_password_more_recently_than_username = false; |
| blink::WebInputElement password = iter->second.password_field; |
| if (password.isAutofilled()) { |
| @@ -337,7 +358,7 @@ bool PasswordAutofillAgent::TextDidChangeInTextField( |
| // But refresh the popup. Note, since this is ours, return true to signal |
| // no further processing is required. |
| if (iter->second.backspace_pressed_last) { |
| - ShowSuggestionPopup(iter->second.fill_data, username, false); |
| + ShowSuggestionPopup(iter->second.fill_data, element, false); |
| return true; |
| } |
| @@ -349,6 +370,10 @@ bool PasswordAutofillAgent::TextDidChangeInTextField( |
| if (element.value().length() > kMaximumTextSizeForAutocomplete) |
| return false; |
| + // Don't let autofill overwrite an explicit change made by the user. |
| + if (iter->second.user_changed_password_more_recently_than_username) |
| + return false; |
| + |
| // The caret position should have already been updated. |
| PerformInlineAutocomplete(element, password, iter->second.fill_data); |
| return true; |
| @@ -790,6 +815,7 @@ void PasswordAutofillAgent::OnFillPasswordForm( |
| password_info.fill_data = form_data; |
| password_info.password_field = password_element; |
| login_to_password_info_[username_element] = password_info; |
| + password_to_username_[password_element] = username_element; |
| FormData form; |
| FormFieldData field; |
| @@ -807,6 +833,11 @@ void PasswordAutofillAgent::OnSetLoggingState(bool active) { |
| //////////////////////////////////////////////////////////////////////////////// |
| // PasswordAutofillAgent, private: |
| +PasswordAutofillAgent::PasswordInfo::PasswordInfo() |
| + : backspace_pressed_last(false), |
| + user_changed_password_more_recently_than_username(false) { |
| +} |
| + |
| void PasswordAutofillAgent::GetSuggestions( |
| const PasswordFormFillData& fill_data, |
| const base::string16& input, |
| @@ -1034,10 +1065,12 @@ void PasswordAutofillAgent::PerformInlineAutocomplete( |
| void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) { |
| for (LoginToPasswordInfoMap::iterator iter = login_to_password_info_.begin(); |
| iter != login_to_password_info_.end();) { |
| - if (iter->first.document().frame() == frame) |
| + if (iter->first.document().frame() == frame) { |
| + password_to_username_.erase(iter->second.password_field); |
| login_to_password_info_.erase(iter++); |
| - else |
| + } else { |
| ++iter; |
| + } |
| } |
| for (FrameToPasswordFormMap::iterator iter = |
| provisionally_saved_forms_.begin(); |