| 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 fd52df402f4af45b7093dd304339c83e79794f98..9e3e0d87fef189c727540f73b52222a8dd24e80b 100644
|
| --- a/components/autofill/content/renderer/password_autofill_agent.cc
|
| +++ b/components/autofill/content/renderer/password_autofill_agent.cc
|
| @@ -273,7 +273,7 @@ void PasswordAutofillAgent::PasswordValueGatekeeper::Reset() {
|
|
|
| void PasswordAutofillAgent::PasswordValueGatekeeper::ShowValue(
|
| blink::WebInputElement* element) {
|
| - if (!element->isNull() && !element->suggestedValue().isNull())
|
| + if (!element->isNull() && !element->suggestedValue().isEmpty())
|
| element->setValue(element->suggestedValue(), true);
|
| }
|
|
|
| @@ -284,13 +284,18 @@ bool PasswordAutofillAgent::TextFieldDidEndEditing(
|
| if (iter == login_to_password_info_.end())
|
| return false;
|
|
|
| - const PasswordFormFillData& fill_data = iter->second.fill_data;
|
| + const PasswordInfo& password_info = iter->second;
|
| + // Don't let autofill overwrite an explicit change made by the user.
|
| + if (password_info.password_was_edited_last)
|
| + return false;
|
| +
|
| + const PasswordFormFillData& fill_data = password_info.fill_data;
|
|
|
| // If wait_for_username is false, we should have filled when the text changed.
|
| if (!fill_data.wait_for_username)
|
| return false;
|
|
|
| - blink::WebInputElement password = iter->second.password_field;
|
| + blink::WebInputElement password = password_info.password_field;
|
| if (!IsElementEditable(password))
|
| return false;
|
|
|
| @@ -308,6 +313,9 @@ 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()) {
|
| // Some login forms have event handlers that put a hash of the password into
|
| // a hidden field and then clear the password (http://crbug.com/28910,
|
| @@ -317,18 +325,25 @@ bool PasswordAutofillAgent::TextDidChangeInTextField(
|
| // password will be saved here.
|
| ProvisionallySavePassword(
|
| element.document().frame(), element.form(), RESTRICTION_NONE);
|
| +
|
| + PasswordToLoginMap::iterator iter = password_to_username_.find(element);
|
| + if (iter != password_to_username_.end()) {
|
| + login_to_password_info_[iter->second].password_was_edited_last = true;
|
| + // Note that the suggested value of |mutable_element| was reset when its
|
| + // value changed.
|
| + mutable_element.setAutofilled(false);
|
| + }
|
| return false;
|
| }
|
|
|
| - LoginToPasswordInfoMap::const_iterator iter =
|
| - login_to_password_info_.find(element);
|
| + LoginToPasswordInfoMap::iterator iter = login_to_password_info_.find(element);
|
| if (iter == login_to_password_info_.end())
|
| return false;
|
|
|
| // 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);
|
| + iter->second.password_was_edited_last = false;
|
|
|
| blink::WebInputElement password = iter->second.password_field;
|
| if (password.isAutofilled()) {
|
| @@ -349,7 +364,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;
|
| }
|
|
|
| @@ -388,21 +403,21 @@ bool PasswordAutofillAgent::FillSuggestion(
|
| const blink::WebString& username,
|
| const blink::WebString& password) {
|
| blink::WebInputElement username_element;
|
| - PasswordInfo password_info;
|
| + PasswordInfo* password_info;
|
|
|
| if (!FindLoginInfo(node, &username_element, &password_info) ||
|
| !IsElementAutocompletable(username_element) ||
|
| - !IsElementAutocompletable(password_info.password_field)) {
|
| + !IsElementAutocompletable(password_info->password_field)) {
|
| return false;
|
| }
|
|
|
| - base::string16 current_username = username_element.value();
|
| + password_info->password_was_edited_last = false;
|
| username_element.setValue(username, true);
|
| username_element.setAutofilled(true);
|
| username_element.setSelectionRange(username.length(), username.length());
|
|
|
| - password_info.password_field.setValue(password, true);
|
| - password_info.password_field.setAutofilled(true);
|
| + password_info->password_field.setValue(password, true);
|
| + password_info->password_field.setAutofilled(true);
|
|
|
| return true;
|
| }
|
| @@ -412,11 +427,11 @@ bool PasswordAutofillAgent::PreviewSuggestion(
|
| const blink::WebString& username,
|
| const blink::WebString& password) {
|
| blink::WebInputElement username_element;
|
| - PasswordInfo password_info;
|
| + PasswordInfo* password_info;
|
|
|
| if (!FindLoginInfo(node, &username_element, &password_info) ||
|
| !IsElementAutocompletable(username_element) ||
|
| - !IsElementAutocompletable(password_info.password_field)) {
|
| + !IsElementAutocompletable(password_info->password_field)) {
|
| return false;
|
| }
|
|
|
| @@ -428,9 +443,9 @@ bool PasswordAutofillAgent::PreviewSuggestion(
|
| username_selection_start_,
|
| username_element.suggestedValue().length());
|
|
|
| - was_password_autofilled_ = password_info.password_field.isAutofilled();
|
| - password_info.password_field.setSuggestedValue(password);
|
| - password_info.password_field.setAutofilled(true);
|
| + was_password_autofilled_ = password_info->password_field.isAutofilled();
|
| + password_info->password_field.setSuggestedValue(password);
|
| + password_info->password_field.setAutofilled(true);
|
|
|
| return true;
|
| }
|
| @@ -438,11 +453,11 @@ bool PasswordAutofillAgent::PreviewSuggestion(
|
| bool PasswordAutofillAgent::DidClearAutofillSelection(
|
| const blink::WebNode& node) {
|
| blink::WebInputElement username_element;
|
| - PasswordInfo password_info;
|
| + PasswordInfo* password_info;
|
| if (!FindLoginInfo(node, &username_element, &password_info))
|
| return false;
|
|
|
| - ClearPreview(&username_element, &password_info.password_field);
|
| + ClearPreview(&username_element, &password_info->password_field);
|
| return true;
|
| }
|
|
|
| @@ -811,6 +826,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;
|
| @@ -828,6 +844,10 @@ void PasswordAutofillAgent::OnSetLoggingState(bool active) {
|
| ////////////////////////////////////////////////////////////////////////////////
|
| // PasswordAutofillAgent, private:
|
|
|
| +PasswordAutofillAgent::PasswordInfo::PasswordInfo()
|
| + : backspace_pressed_last(false), password_was_edited_last(false) {
|
| +}
|
| +
|
| void PasswordAutofillAgent::GetSuggestions(
|
| const PasswordFormFillData& fill_data,
|
| const base::string16& input,
|
| @@ -1055,10 +1075,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();
|
| @@ -1072,7 +1094,7 @@ void PasswordAutofillAgent::FrameClosing(const blink::WebFrame* frame) {
|
|
|
| bool PasswordAutofillAgent::FindLoginInfo(const blink::WebNode& node,
|
| blink::WebInputElement* found_input,
|
| - PasswordInfo* found_password) {
|
| + PasswordInfo** found_password) {
|
| if (!node.isElementNode())
|
| return false;
|
|
|
| @@ -1086,7 +1108,7 @@ bool PasswordAutofillAgent::FindLoginInfo(const blink::WebNode& node,
|
| return false;
|
|
|
| *found_input = input;
|
| - *found_password = iter->second;
|
| + *found_password = &iter->second;
|
| return true;
|
| }
|
|
|
|
|