| 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 ce2f1031844cf0f582c32be523841057e09e4ebd..754ff32c3236b398b49df8416cc1d62521503029 100644
|
| --- a/components/autofill/content/renderer/password_autofill_agent.cc
|
| +++ b/components/autofill/content/renderer/password_autofill_agent.cc
|
| @@ -164,39 +164,6 @@ bool IsElementEditable(const WebKit::WebInputElement& element) {
|
| return element.isEnabled() && !element.isReadOnly();
|
| }
|
|
|
| -void FillForm(FormElements* fe, const FormData& data) {
|
| - if (!fe->form_element.autoComplete())
|
| - return;
|
| -
|
| - std::map<base::string16, base::string16> data_map;
|
| - for (size_t i = 0; i < data.fields.size(); i++)
|
| - data_map[data.fields[i].name] = data.fields[i].value;
|
| -
|
| - for (FormInputElementMap::iterator it = fe->input_elements.begin();
|
| - it != fe->input_elements.end(); ++it) {
|
| - WebKit::WebInputElement element = it->second;
|
| - // Don't fill a form that has pre-filled values distinct from the ones we
|
| - // want to fill with.
|
| - if (!element.value().isEmpty() && element.value() != data_map[it->first])
|
| - return;
|
| -
|
| - // Don't fill forms with uneditable fields or fields with autocomplete
|
| - // disabled.
|
| - if (!IsElementEditable(element) || !element.autoComplete())
|
| - return;
|
| - }
|
| -
|
| - for (FormInputElementMap::iterator it = fe->input_elements.begin();
|
| - it != fe->input_elements.end(); ++it) {
|
| - WebKit::WebInputElement element = it->second;
|
| -
|
| - // TODO(tkent): Check maxlength and pattern.
|
| - element.setValue(data_map[it->first]);
|
| - element.setAutofilled(true);
|
| - element.dispatchFormControlChangeEvent();
|
| - }
|
| -}
|
| -
|
| void SetElementAutofilled(WebKit::WebInputElement* element, bool autofilled) {
|
| if (element->isAutofilled() == autofilled)
|
| return;
|
| @@ -250,7 +217,9 @@ bool PasswordAutofillAgent::TextFieldDidEndEditing(
|
|
|
| // Do not set selection when ending an editing session, otherwise it can
|
| // mess with focus.
|
| - FillUserNameAndPassword(&username, &password, fill_data, true, false);
|
| + FillUserNameAndPassword(&username, &password, fill_data,
|
| + true /* exact_username_match */,
|
| + false /* set_selection */);
|
| return true;
|
| }
|
|
|
| @@ -331,7 +300,9 @@ bool PasswordAutofillAgent::DidAcceptAutofillSuggestion(
|
| // will do the rest.
|
| input.setValue(value, true);
|
| return FillUserNameAndPassword(&input, &password.password_field,
|
| - password.fill_data, true, true);
|
| + password.fill_data,
|
| + true /* exact_username_match */,
|
| + true /* set_selection */);
|
| }
|
|
|
| bool PasswordAutofillAgent::DidClearAutofillSelection(
|
| @@ -516,11 +487,6 @@ void PasswordAutofillAgent::OnFillPasswordForm(
|
| for (iter = forms.begin(); iter != forms.end(); ++iter) {
|
| scoped_ptr<FormElements> form_elements(*iter);
|
|
|
| - // If wait_for_username is true, we don't want to initially fill the form
|
| - // until the user types in a valid username.
|
| - if (!form_data.wait_for_username)
|
| - FillForm(form_elements.get(), form_data.basic_data);
|
| -
|
| // Attach autocomplete listener to enable selecting alternate logins.
|
| // First, get pointers to username element.
|
| WebKit::WebInputElement username_element =
|
| @@ -531,6 +497,11 @@ void PasswordAutofillAgent::OnFillPasswordForm(
|
| WebKit::WebInputElement 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
|
| + // until the user types in a valid username.
|
| + if (!form_data.wait_for_username)
|
| + FillFormOnPasswordRecieved(form_data, username_element, password_element);
|
| +
|
| // We might have already filled this form if there are two <form> elements
|
| // with identical markup.
|
| if (login_to_password_info_.find(username_element) !=
|
| @@ -625,6 +596,33 @@ bool PasswordAutofillAgent::ShowSuggestionPopup(
|
| return !suggestions.empty();
|
| }
|
|
|
| +void PasswordAutofillAgent::FillFormOnPasswordRecieved(
|
| + const PasswordFormFillData& fill_data,
|
| + WebKit::WebInputElement username_element,
|
| + WebKit::WebInputElement password_element) {
|
| + if (!username_element.form().autoComplete())
|
| + return;
|
| +
|
| + // If we can't modify the password, don't try to set the username
|
| + if (!IsElementEditable(password_element) || !password_element.autoComplete())
|
| + return;
|
| +
|
| + // Try to set the username to the preferred name, but only if the field
|
| + // can be set and isn't prefilled.
|
| + if (IsElementEditable(username_element) &&
|
| + username_element.autoComplete() &&
|
| + username_element.value().isEmpty()) {
|
| + // TODO(tkent): Check maxlength and pattern.
|
| + username_element.setValue(fill_data.basic_data.fields[0].value);
|
| + }
|
| +
|
| + // Fill if we have an exact match for the username. Note that this sets
|
| + // username to autofilled.
|
| + FillUserNameAndPassword(&username_element, &password_element, fill_data,
|
| + true /* exact_username_match */,
|
| + false /* set_selection */);
|
| +}
|
| +
|
| bool PasswordAutofillAgent::FillUserNameAndPassword(
|
| WebKit::WebInputElement* username_element,
|
| WebKit::WebInputElement* password_element,
|
| @@ -676,17 +674,32 @@ bool PasswordAutofillAgent::FillUserNameAndPassword(
|
| if (password.empty())
|
| return false; // No match was found.
|
|
|
| - // Input matches the username, fill in required values.
|
| - username_element->setValue(username);
|
| + // TODO(tkent): Check maxlength and pattern for both username and password
|
| + // fields.
|
| +
|
| + // Don't fill username if password can't be set.
|
| + if (!IsElementEditable(*password_element) ||
|
| + !password_element->autoComplete()) {
|
| + return false;
|
| + }
|
|
|
| - if (set_selection) {
|
| - username_element->setSelectionRange(current_username.length(),
|
| - username.length());
|
| + // Input matches the username, fill in required values.
|
| + if (IsElementEditable(*username_element) &&
|
| + username_element->autoComplete()) {
|
| + username_element->setValue(username);
|
| + SetElementAutofilled(username_element, true);
|
| +
|
| + 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;
|
| }
|
|
|
| - SetElementAutofilled(username_element, true);
|
| - if (IsElementEditable(*password_element))
|
| - password_element->setValue(password);
|
| + password_element->setValue(password);
|
| SetElementAutofilled(password_element, true);
|
| return true;
|
| }
|
| @@ -715,7 +728,9 @@ void PasswordAutofillAgent::PerformInlineAutocomplete(
|
| #if !defined(OS_ANDROID)
|
| // Fill the user and password field with the most relevant match. Android
|
| // only fills in the fields after the user clicks on the suggestion popup.
|
| - FillUserNameAndPassword(&username, &password, fill_data, false, true);
|
| + FillUserNameAndPassword(&username, &password, fill_data,
|
| + false /* exact_username_match */,
|
| + true /* set_selection */);
|
| #endif
|
| }
|
|
|
|
|