Chromium Code Reviews| Index: components/autofill/content/renderer/password_generation_agent.cc |
| diff --git a/components/autofill/content/renderer/password_generation_agent.cc b/components/autofill/content/renderer/password_generation_agent.cc |
| index 0776b0ebf355bc83112ad59d2f78f5f804ab8522..ec28f365ce63d487028161e1f785dc23d22dfbd4 100644 |
| --- a/components/autofill/content/renderer/password_generation_agent.cc |
| +++ b/components/autofill/content/renderer/password_generation_agent.cc |
| @@ -18,6 +18,7 @@ |
| #include "components/autofill/core/common/password_form.h" |
| #include "components/autofill/core/common/password_form_generation_data.h" |
| #include "components/autofill/core/common/password_generation_util.h" |
| +#include "components/autofill/core/common/signatures_util.h" |
| #include "content/public/renderer/render_frame.h" |
| #include "content/public/renderer/render_view.h" |
| #include "google_apis/gaia/gaia_urls.h" |
| @@ -57,46 +58,39 @@ bool ContainsURL(const std::vector<GURL>& urls, const GURL& url) { |
| return std::find(urls.begin(), urls.end(), url) != urls.end(); |
| } |
| -// Finds a form in |forms| that has the same action and name as |form|. |
| -// If the action of a form in |forms| is empty, it uses |base_url| as action. It |
| -// also strips parameters of the action. |
| +// Calculates the signature of |form| and searches it in |forms|. |
| const PasswordFormGenerationData* FindFormGenerationData( |
| const std::vector<PasswordFormGenerationData>& forms, |
| - const PasswordForm& form, |
| - const GURL& base_url) { |
| + const PasswordForm& form) { |
| + FormSignature form_signature = CalculateFormSignature(form.form_data); |
|
dvadym
2016/09/07 17:29:35
I was wondering, whether we want to cache this sig
|
| for (const auto& form_it : forms) { |
| - GURL action = form_it.action; |
| - if (action.is_empty()) |
| - action = base_url; |
| - action = form_util::StripAuthAndParams(action); |
| - if (form_it.name == form.form_data.name && action == form.action) |
| + if (form_it.form_signature == form_signature) |
| return &form_it; |
| } |
| return nullptr; |
| } |
| // This function returns a vector of password fields into which Chrome should |
| -// fill the generated password. It assumes that |field_data| describes the field |
| -// where Chrome shows the password generation prompt. It returns no more |
| +// fill the generated password. It assumes that |field_signature| describes the |
| +// field where Chrome shows the password generation prompt. It returns no more |
| // than 2 elements. |
| std::vector<blink::WebInputElement> FindPasswordElementsForGeneration( |
| const std::vector<blink::WebInputElement>& all_password_elements, |
| - const base::string16& field_name) { |
| - auto iter = |
| - std::find_if(all_password_elements.begin(), all_password_elements.end(), |
| - [&field_name](const blink::WebInputElement& input) { |
| - // Make explicit conversion before comparing with string16. |
| - base::string16 input_name = input.nameForAutofill(); |
| - return input_name == field_name; |
| - }); |
| + const FieldSignature field_signature) { |
| + auto iter = std::find_if( |
| + all_password_elements.begin(), all_password_elements.end(), |
| + [&field_signature](const blink::WebInputElement& input) { |
| + FieldSignature signature = CalculateFieldSignatureByNameAndType( |
| + input.nameForAutofill(), input.formControlType().utf8()); |
| + return signature == field_signature; |
| + }); |
| std::vector<blink::WebInputElement> passwords; |
| // We copy not more than 2 fields because occasionally there are forms where |
| // the security question answers are put in password fields and we don't want |
| // to fill those. |
| - for (; iter != all_password_elements.end() && passwords.size() < 2; ++iter) { |
| + for (; iter != all_password_elements.end() && passwords.size() < 2; ++iter) |
| passwords.push_back(*iter); |
| - } |
| return passwords; |
| } |
| @@ -390,9 +384,8 @@ void PasswordGenerationAgent::DetermineGenerationElement() { |
| << "blacklisted"; |
| continue; |
| } else { |
| - generation_data = FindFormGenerationData( |
| - generation_enabled_forms_, *possible_password_form, |
| - render_frame()->GetWebFrame()->document().baseURL()); |
| + generation_data = FindFormGenerationData(generation_enabled_forms_, |
| + *possible_password_form); |
| if (!generation_data) { |
| if (AutocompleteAttributesSetForGeneration(*possible_password_form)) { |
| VLOG(2) << "Ignoring lack of Autofill signal due to Autocomplete " |
| @@ -412,7 +405,7 @@ void PasswordGenerationAgent::DetermineGenerationElement() { |
| std::vector<blink::WebInputElement> password_elements = |
| generation_data ? FindPasswordElementsForGeneration( |
| possible_form_data.password_elements, |
| - generation_data->generation_field.name) |
| + generation_data->field_signature) |
| : possible_form_data.password_elements; |
| if (password_elements.empty()) { |
| // It might be if JavaScript changes field names. |
| @@ -574,7 +567,10 @@ void PasswordGenerationAgent::UserTriggeredGeneratePassword() { |
| std::vector<blink::WebInputElement> password_elements; |
| GetAccountCreationPasswordFields(control_elements, &password_elements); |
| password_elements = FindPasswordElementsForGeneration( |
| - password_elements, last_focused_password_element_.nameForAutofill()); |
| + password_elements, |
| + CalculateFieldSignatureByNameAndType( |
| + last_focused_password_element_.nameForAutofill(), |
| + last_focused_password_element_.formControlType().utf8())); |
| generation_form_data_.reset(new AccountCreationFormData( |
| make_linked_ptr(password_form.release()), password_elements)); |
| is_manually_triggered_ = true; |