| Index: components/autofill/content/renderer/password_form_conversion_utils.cc
|
| diff --git a/components/autofill/content/renderer/password_form_conversion_utils.cc b/components/autofill/content/renderer/password_form_conversion_utils.cc
|
| index be13e1b92b88072f2a0ff4bc9d8d435da006e40f..d62f5a1fd36dcf109e5776fb7a001928c6074b5e 100644
|
| --- a/components/autofill/content/renderer/password_form_conversion_utils.cc
|
| +++ b/components/autofill/content/renderer/password_form_conversion_utils.cc
|
| @@ -4,10 +4,13 @@
|
|
|
| #include "components/autofill/content/renderer/password_form_conversion_utils.h"
|
|
|
| +#include <vector>
|
| +
|
| #include "base/lazy_instance.h"
|
| #include "base/memory/scoped_ptr.h"
|
| #include "base/strings/string_util.h"
|
| #include "components/autofill/content/renderer/form_autofill_util.h"
|
| +#include "components/autofill/core/common/form_data_predictions.h"
|
| #include "components/autofill/core/common/password_form.h"
|
| #include "third_party/WebKit/public/platform/WebString.h"
|
| #include "third_party/WebKit/public/web/WebDocument.h"
|
| @@ -177,6 +180,42 @@ bool LocateSpecificPasswords(std::vector<WebInputElement> passwords,
|
| return true;
|
| }
|
|
|
| +void FindPredictedUsernameElement(
|
| + const WebFormElement& form,
|
| + const std::map<autofill::FormData, autofill::FormFieldData>&
|
| + form_predictions,
|
| + WebVector<WebFormControlElement>* control_elements,
|
| + WebInputElement* predicted_username_element) {
|
| + FormData form_data;
|
| + if (!WebFormElementToFormData(form, WebFormControlElement(), REQUIRE_NONE,
|
| + EXTRACT_NONE, &form_data, nullptr))
|
| + return;
|
| +
|
| + // Prediction forms are not user submitted, but |form| can be user submitted.
|
| + // We don't care about this flag for finding predictions, so set it to false.
|
| + form_data.user_submitted = false;
|
| + auto predictions_iterator = form_predictions.find(form_data);
|
| + if (predictions_iterator == form_predictions.end())
|
| + return;
|
| +
|
| + std::vector<blink::WebFormControlElement> autofillable_elements =
|
| + ExtractAutofillableElementsFromSet(*control_elements, REQUIRE_NONE);
|
| + DCHECK_EQ(autofillable_elements.size(), form_data.fields.size());
|
| +
|
| + const autofill::FormFieldData& username_field = predictions_iterator->second;
|
| + autofill::FormFieldData form_field;
|
| + for (size_t i = 0; i < autofillable_elements.size(); ++i) {
|
| + if (form_data.fields[i].SameFieldAs(username_field)) {
|
| + WebInputElement* input_element =
|
| + toWebInputElement(&autofillable_elements[i]);
|
| + if (input_element) {
|
| + *predicted_username_element = *input_element;
|
| + }
|
| + break;
|
| + }
|
| + }
|
| +}
|
| +
|
| // Get information about a login form encapsulated in a PasswordForm struct.
|
| // If an element of |form| has an entry in |nonscript_modified_values|, the
|
| // associated string is used instead of the element's value to create
|
| @@ -185,7 +224,9 @@ void GetPasswordForm(
|
| const WebFormElement& form,
|
| PasswordForm* password_form,
|
| const std::map<const blink::WebInputElement, blink::WebString>*
|
| - nonscript_modified_values) {
|
| + nonscript_modified_values,
|
| + const std::map<autofill::FormData, autofill::FormFieldData>*
|
| + form_predictions) {
|
| WebInputElement latest_input_element;
|
| WebInputElement username_element;
|
| password_form->username_marked_by_site = false;
|
| @@ -275,6 +316,27 @@ void GetPasswordForm(
|
| }
|
| password_form->layout = SequenceToLayout(layout_sequence);
|
|
|
| + WebInputElement predicted_username_element;
|
| + if (form_predictions) {
|
| + FindPredictedUsernameElement(form, *form_predictions, &control_elements,
|
| + &predicted_username_element);
|
| + }
|
| + // Let server predictions override the selection of the username field. This
|
| + // allows instant adjusting without changing Chromium code.
|
| + if (!predicted_username_element.isNull() &&
|
| + username_element != predicted_username_element) {
|
| + auto it =
|
| + find(other_possible_usernames.begin(), other_possible_usernames.end(),
|
| + predicted_username_element.value());
|
| + if (it != other_possible_usernames.end())
|
| + other_possible_usernames.erase(it);
|
| + if (!username_element.isNull()) {
|
| + other_possible_usernames.push_back(username_element.value());
|
| + }
|
| + username_element = predicted_username_element;
|
| + password_form->was_parsed_using_autofill_predictions = true;
|
| + }
|
| +
|
| if (!username_element.isNull()) {
|
| password_form->username_element = username_element.nameForAutofill();
|
| base::string16 username_value = username_element.value();
|
| @@ -353,12 +415,15 @@ void GetPasswordForm(
|
| scoped_ptr<PasswordForm> CreatePasswordForm(
|
| const WebFormElement& web_form,
|
| const std::map<const blink::WebInputElement, blink::WebString>*
|
| - nonscript_modified_values) {
|
| + nonscript_modified_values,
|
| + const std::map<autofill::FormData, autofill::FormFieldData>*
|
| + form_predictions) {
|
| if (web_form.isNull())
|
| return scoped_ptr<PasswordForm>();
|
|
|
| scoped_ptr<PasswordForm> password_form(new PasswordForm());
|
| - GetPasswordForm(web_form, password_form.get(), nonscript_modified_values);
|
| + GetPasswordForm(web_form, password_form.get(), nonscript_modified_values,
|
| + form_predictions);
|
|
|
| if (!password_form->action.is_valid())
|
| return scoped_ptr<PasswordForm>();
|
|
|