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(); |