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 86ff3779dc76fb185f1e36c899ca5c95f9d6cf88..3a0391768ed7b332543e8831c2fb35a39a965b69 100644 |
--- a/components/autofill/content/renderer/password_autofill_agent.cc |
+++ b/components/autofill/content/renderer/password_autofill_agent.cc |
@@ -71,6 +71,11 @@ static bool FindFormInputElements(blink::WebFormElement* fe, |
// autofill it. If we don't find any one of them, abort processing this |
// form; it can't be the right one. |
for (size_t j = 0; j < data.fields.size(); j++) { |
+ // The password form may not contain a username field |
+ // (http://crbug.com/406343), but continue autofilling password field. |
+ if (data.fields[j].name.empty()) |
vabr (Chromium)
2014/09/24 16:17:21
Looking at InitPasswordFormFillData, the username
Pritam Nikam
2014/09/25 07:22:28
Done.
I've refactored code, and these changes are
|
+ continue; |
+ |
blink::WebVector<blink::WebNode> temp_elements; |
fe->getNamedElements(data.fields[j].name, temp_elements); |
@@ -218,6 +223,10 @@ void LogHTMLForm(SavePasswordProgressLogger* logger, |
GURL(form.action().utf8())); |
} |
+bool FillDataContainsUsername(const PasswordFormFillData& fill_data) { |
+ return !fill_data.basic_data.fields[0].name.empty(); |
+} |
+ |
} // namespace |
//////////////////////////////////////////////////////////////////////////////// |
@@ -802,13 +811,22 @@ void PasswordAutofillAgent::OnFillPasswordForm( |
scoped_ptr<FormElements> form_elements(*iter); |
// Attach autocomplete listener to enable selecting alternate logins. |
- // First, get pointers to username element. |
- blink::WebInputElement username_element = |
- form_elements->input_elements[form_data.basic_data.fields[0].name]; |
+ blink::WebInputElement username_element, password_element; |
+ |
+ // Check whether the password form has a username input field. |
+ bool form_contains_username_field = FillDataContainsUsername(form_data); |
+ if (form_contains_username_field) { |
+ username_element = |
+ form_elements->input_elements[form_data.basic_data.fields[0].name]; |
+ } |
+ |
+ // No password field, bail out. |
+ if (form_data.basic_data.fields[1].name.empty()) |
+ break; |
// Get pointer to password element. (We currently only support single |
// password forms). |
- blink::WebInputElement password_element = |
+ password_element = |
form_elements->input_elements[form_data.basic_data.fields[1].name]; |
// If wait_for_username is true, we don't want to initially fill the form |
@@ -830,8 +848,11 @@ void PasswordAutofillAgent::OnFillPasswordForm( |
FormData form; |
FormFieldData field; |
- FindFormAndFieldForFormControlElement( |
- username_element, &form, &field, REQUIRE_NONE); |
+ if (form_contains_username_field) { |
+ FindFormAndFieldForFormControlElement( |
+ username_element, &form, &field, REQUIRE_NONE); |
+ } |
+ |
Send(new AutofillHostMsg_AddPasswordFormMapping( |
routing_id(), field, form_data)); |
} |
@@ -929,8 +950,9 @@ void PasswordAutofillAgent::FillFormOnPasswordRecieved( |
if (password_element.document().frame()->parent()) |
return; |
+ bool form_contains_username_field = FillDataContainsUsername(fill_data); |
if (!ShouldIgnoreAutocompleteOffForPasswordFields() && |
- !username_element.form().autoComplete()) |
+ form_contains_username_field && !username_element.form().autoComplete()) |
return; |
// If we can't modify the password, don't try to set the username |
@@ -939,7 +961,8 @@ void PasswordAutofillAgent::FillFormOnPasswordRecieved( |
// Try to set the username to the preferred name, but only if the field |
// can be set and isn't prefilled. |
- if (IsElementAutocompletable(username_element) && |
+ if (form_contains_username_field && |
+ IsElementAutocompletable(username_element) && |
username_element.value().isEmpty()) { |
// TODO(tkent): Check maxlength and pattern. |
username_element.setValue(fill_data.basic_data.fields[0].value, true); |
@@ -960,7 +983,6 @@ bool PasswordAutofillAgent::FillUserNameAndPassword( |
const PasswordFormFillData& fill_data, |
bool exact_username_match, |
bool set_selection) { |
- base::string16 current_username = username_element->value(); |
// username and password will contain the match found if any. |
base::string16 username; |
base::string16 password; |
@@ -969,65 +991,71 @@ bool PasswordAutofillAgent::FillUserNameAndPassword( |
if (!IsElementAutocompletable(*password_element)) |
return false; |
- // Look for any suitable matches to current field text. |
- if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, |
vabr (Chromium)
2014/09/24 16:17:21
Wouldn't this actually work just fine if there was
Pritam Nikam
2014/09/25 07:22:27
Done.
Right! I did it this way now.
vabr (Chromium)
2014/09/25 10:39:59
Actually, I don't think you did it the way suggest
|
- current_username, |
- exact_username_match)) { |
- username = fill_data.basic_data.fields[0].value; |
- password = fill_data.basic_data.fields[1].value; |
- } else { |
- // Scan additional logins for a match. |
- PasswordFormFillData::LoginCollection::const_iterator iter; |
- for (iter = fill_data.additional_logins.begin(); |
- iter != fill_data.additional_logins.end(); |
- ++iter) { |
- if (DoUsernamesMatch( |
- iter->first, current_username, exact_username_match)) { |
- username = iter->first; |
- password = iter->second.password; |
- break; |
- } |
- } |
+ if (FillDataContainsUsername(fill_data)) { |
+ base::string16 current_username = username_element->value(); |
- // Check possible usernames. |
- if (username.empty() && password.empty()) { |
- for (PasswordFormFillData::UsernamesCollection::const_iterator iter = |
- fill_data.other_possible_usernames.begin(); |
- iter != fill_data.other_possible_usernames.end(); |
+ // Look for any suitable matches to current field text. |
+ if (DoUsernamesMatch(fill_data.basic_data.fields[0].value, |
+ current_username, |
+ exact_username_match)) { |
+ username = fill_data.basic_data.fields[0].value; |
+ password = fill_data.basic_data.fields[1].value; |
+ } else { |
+ // Scan additional logins for a match. |
+ PasswordFormFillData::LoginCollection::const_iterator iter; |
+ for (iter = fill_data.additional_logins.begin(); |
+ iter != fill_data.additional_logins.end(); |
++iter) { |
- for (size_t i = 0; i < iter->second.size(); ++i) { |
- if (DoUsernamesMatch( |
- iter->second[i], current_username, exact_username_match)) { |
- usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED; |
- username = iter->second[i]; |
- password = iter->first.password; |
- break; |
+ if (DoUsernamesMatch( |
+ iter->first, current_username, exact_username_match)) { |
+ username = iter->first; |
+ password = iter->second.password; |
+ break; |
+ } |
+ } |
+ |
+ // Check possible usernames. |
+ if (username.empty() && password.empty()) { |
+ for (PasswordFormFillData::UsernamesCollection::const_iterator iter = |
+ fill_data.other_possible_usernames.begin(); |
+ iter != fill_data.other_possible_usernames.end(); |
+ ++iter) { |
+ for (size_t i = 0; i < iter->second.size(); ++i) { |
+ if (DoUsernamesMatch( |
+ iter->second[i], current_username, exact_username_match)) { |
+ usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED; |
+ username = iter->second[i]; |
+ password = iter->first.password; |
+ break; |
+ } |
} |
+ if (!username.empty() && !password.empty()) |
+ break; |
} |
- if (!username.empty() && !password.empty()) |
- break; |
} |
} |
- } |
- if (password.empty()) |
- return false; // No match was found. |
+ if (password.empty()) |
+ return false; // No match was found. |
- // TODO(tkent): Check maxlength and pattern for both username and password |
- // fields. |
+ // TODO(tkent): Check maxlength and pattern for both username and password |
+ // fields. |
- // Input matches the username, fill in required values. |
- if (IsElementAutocompletable(*username_element)) { |
- username_element->setValue(username, true); |
- username_element->setAutofilled(true); |
+ // Input matches the username, fill in required values. |
+ if (IsElementAutocompletable(*username_element)) { |
+ username_element->setValue(username, true); |
+ username_element->setAutofilled(true); |
- if (set_selection) { |
- username_element->setSelectionRange(current_username.length(), |
- username.length()); |
+ if (set_selection) { |
+ username_element->setSelectionRange(current_username.length(), |
+ username.length()); |
+ } |
+ } else if (current_username != username) { |
+ // If the username can't be filled and it doesn't match a saved password |
+ // as is, don't autofill a password. |
+ return false; |
} |
- } else if (current_username != username) { |
- // If the username can't be filled and it doesn't match a saved password |
- // as is, don't autofill a password. |
- return false; |
+ } else { |
+ password = fill_data.basic_data.fields[1].value; |
} |
// Wait to fill in the password until a user gesture occurs. This is to make |
@@ -1074,7 +1102,9 @@ 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) { |
+ // There may not be a username field, so get the frame from the password |
+ // field. |
+ if (iter->second.password_field.document().frame() == frame) { |
password_to_username_.erase(iter->second.password_field); |
login_to_password_info_.erase(iter++); |
} else { |