Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Unified Diff: components/autofill/content/renderer/password_autofill_agent.cc

Issue 597983003: Refactor PasswordAutofillAgent: methods to functions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Changes as per review comments. Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/autofill/content/renderer/password_autofill_agent.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 480bfc617eb95ca620779cf045b0eeb3c9a37899..4760c17075af01a7a6a8406e451112d91076cf7b 100644
--- a/components/autofill/content/renderer/password_autofill_agent.cc
+++ b/components/autofill/content/renderer/password_autofill_agent.cc
@@ -225,6 +225,188 @@ bool FillDataContainsUsername(const PasswordFormFillData& fill_data) {
return !fill_data.basic_data.fields[0].name.empty();
}
+// This helper function will fill the |suggestions| and |realms| form the
Garrett Casto 2014/09/30 00:16:41 "fill the |suggestions| and |realms| form the fill
Deepak 2014/09/30 04:07:21 Done.
vabr (Chromium) 2014/09/30 08:19:41 The form->from typo seems to be still present. :)
+// fill_data based on the |input| and return true when suggestion
vabr (Chromium) 2014/09/29 15:19:09 typo: suggestion -> suggestions
Garrett Casto 2014/09/30 00:16:40 Just "|input|" not "the |input|". "Input" is also
Deepak 2014/09/30 04:07:21 Done.
Deepak 2014/09/30 04:07:21 Done.
vabr (Chromium) 2014/09/30 08:19:41 I believe Garrett meant renaming the argument |inp
+// get filled from usernamescollection else return false.
vabr (Chromium) 2014/09/29 15:19:09 nit: Not clear what is meant by the username colle
Garrett Casto 2014/09/30 00:16:40 From |fill_data| isn't specific, all suggestions a
Deepak 2014/09/30 04:07:21 I have made this like: return true when suggestion
Deepak 2014/09/30 04:07:21 Done.
vabr (Chromium) 2014/09/30 08:19:41 2 nits: (1) Replace other_possible_usernames with
+bool GetSuggestions(const PasswordFormFillData& fill_data,
+ const base::string16& input,
+ std::vector<base::string16>* suggestions,
+ std::vector<base::string16>* realms,
+ bool show_all) {
+ bool usernames_shown = false;
+ if (show_all ||
+ StartsWith(fill_data.basic_data.fields[0].value, input, false)) {
+ suggestions->push_back(fill_data.basic_data.fields[0].value);
+ realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm));
+ }
+
+ for (PasswordFormFillData::LoginCollection::const_iterator iter =
+ fill_data.additional_logins.begin();
+ iter != fill_data.additional_logins.end();
+ ++iter) {
+ if (show_all || StartsWith(iter->first, input, false)) {
+ suggestions->push_back(iter->first);
+ realms->push_back(base::UTF8ToUTF16(iter->second.realm));
+ }
+ }
+
+ 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 (show_all || StartsWith(iter->second[i], input, false)) {
+ usernames_shown = true;
+ suggestions->push_back(iter->second[i]);
+ realms->push_back(base::UTF8ToUTF16(iter->first.realm));
+ }
+ }
+ }
+ return usernames_shown;
+}
+
+// This function attempts to set the |username_element]
+// and |password_element| values with the |fill_data|
Garrett Casto 2014/09/30 00:16:41 Line wrapping too early. You should wrap closer to
Deepak 2014/09/30 04:07:22 Acknowledged.
+// returns true when username get selected from possible usernames
vabr (Chromium) 2014/09/29 15:19:10 typo: "username get" -> "a username gets"
Garrett Casto 2014/09/30 00:16:40 I think there is supposed to be a period and "ret
Deepak 2014/09/30 04:07:21 Done.
Deepak 2014/09/30 04:07:22 Done.
+// else returns false.it will also register the password element when
vabr (Chromium) 2014/09/29 15:19:10 nit: Specify that it will register the password el
vabr (Chromium) 2014/09/29 15:19:10 nit: "false.it" -> "false. It"
Deepak 2014/09/30 04:07:21 Done.
+// its value set.
+bool FillUserNameAndPassword(
+ blink::WebInputElement* username_element,
+ blink::WebInputElement* password_element,
+ const PasswordFormFillData& fill_data,
+ bool exact_username_match,
+ bool set_selection,
+ base::Callback<void(blink::WebInputElement*)> gatekeeper_callback) {
+ bool username_selected = false;
Garrett Casto 2014/09/30 00:16:41 |username_selected| is too vague. It's not just if
Deepak 2014/09/30 04:07:21 I have made this "possible_username_selected" to m
vabr (Chromium) 2014/09/30 08:19:41 I would actually suggest |other_possible_username_
vabr (Chromium) 2014/09/30 13:54:53 You seem to have missed this comment as well.
+ // Don't fill username if password can't be set.
+ if (!IsElementAutocompletable(*password_element))
+ return false;
+
+ base::string16 current_username;
+ if (!username_element->isNull()) {
+ current_username = username_element->value();
+ }
+
+ // username and password will contain the match found if any.
+ base::string16 username;
+ base::string16 password;
+
+ // 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) {
+ 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)) {
+ username_selected = true;
+ username = iter->second[i];
+ password = iter->first.password;
+ break;
+ }
+ }
+ if (!username.empty() && !password.empty())
+ break;
+ }
+ }
+ }
+ if (password.empty())
+ return username_selected; // No match was found.
+
+ // TODO(tkent): Check maxlength and pattern for both username and password
+ // fields.
+
+ // Input matches the username, fill in required values.
+ if (!username_element->isNull() &&
+ IsElementAutocompletable(*username_element)) {
+ username_element->setValue(username, true);
+ username_element->setAutofilled(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 username_selected;
+ }
+
+ // Wait to fill in the password until a user gesture occurs. This is to make
+ // sure that we do not fill in the DOM with a password until we believe the
+ // user is intentionally interacting with the page.
+ password_element->setSuggestedValue(password);
+ gatekeeper_callback.Run(password_element);
+
+ password_element->setAutofilled(true);
+ return username_selected;
+}
+
+// Attempts to fill |username_element| and |password_element| with the
Garrett Casto 2014/09/30 00:16:40 As above, be consistent with pronouns. It's more c
+// |fill_data|. Will use the data corresponding to the preferred username,
+// unless the |username_element| already has a value set. In that case,
+// attempts to fill the password matching the already filled username, if
+// such a password exists.gatekeeper_ptr will register the password element.
vabr (Chromium) 2014/09/29 15:19:09 nit: gatekeeper_ptr sounds like a typo. Maybe say
vabr (Chromium) 2014/09/29 15:19:10 nit: space after a full-stop
Deepak 2014/09/30 04:07:21 Done.
Deepak 2014/09/30 04:07:21 Done.
+// returns true when username is selected else return false.
Garrett Casto 2014/09/30 00:16:41 Username is selected is misleading, it's just othe
Deepak 2014/09/30 04:07:21 Done.
+bool FillFormOnPasswordRecieved(
+ const PasswordFormFillData& fill_data,
+ blink::WebInputElement username_element,
+ blink::WebInputElement password_element,
+ base::Callback<void(blink::WebInputElement*)> gatekeeper_callback) {
+ // Do not fill if the password field is in an iframe.
+ DCHECK(password_element.document().frame());
+ if (password_element.document().frame()->parent())
+ return false;
+
+ bool form_contains_username_field = FillDataContainsUsername(fill_data);
+ if (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
+ form_contains_username_field && !username_element.form().autoComplete())
+ return false;
+
+ // If we can't modify the password, don't try to set the username
+ if (!IsElementAutocompletable(password_element))
+ return false;
+
+ // Try to set the username to the preferred name, but only if the field
+ // can be set and isn't prefilled.
+ 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);
+ }
+
+ // Fill if we have an exact match for the username. Note that this sets
+ // username to autofilled.
+ return FillUserNameAndPassword(&username_element,
+ &password_element,
+ fill_data,
+ true /* exact_username_match */,
+ false /* set_selection */,
+ gatekeeper_callback);
+}
+
} // namespace
////////////////////////////////////////////////////////////////////////////////
@@ -310,11 +492,15 @@ bool PasswordAutofillAgent::TextFieldDidEndEditing(
// Do not set selection when ending an editing session, otherwise it can
// mess with focus.
- FillUserNameAndPassword(&username,
- &password,
- fill_data,
- true /* exact_username_match */,
- false /* set_selection */);
+ if (FillUserNameAndPassword(
+ &username,
+ &password,
+ fill_data,
+ true /* exact_username_match */,
+ false /* set_selection */,
+ base::Bind(&PasswordValueGatekeeper::RegisterElement,
+ base::Unretained(&gatekeeper_))))
+ usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED;
vabr (Chromium) 2014/09/29 15:19:10 nit: Please add curly braces around the statement,
Deepak 2014/09/30 04:07:21 Done.
return true;
}
@@ -829,8 +1015,14 @@ void PasswordAutofillAgent::OnFillPasswordForm(
// 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);
+ if (!form_data.wait_for_username &&
+ FillFormOnPasswordRecieved(
+ form_data,
+ username_element,
+ password_element,
+ base::Bind(&PasswordValueGatekeeper::RegisterElement,
+ base::Unretained(&gatekeeper_))))
+ usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED;
// We might have already filled this form if there are two <form> elements
// with identical markup.
@@ -867,42 +1059,6 @@ PasswordAutofillAgent::PasswordInfo::PasswordInfo()
: backspace_pressed_last(false), password_was_edited_last(false) {
}
-void PasswordAutofillAgent::GetSuggestions(
- const PasswordFormFillData& fill_data,
- const base::string16& input,
- std::vector<base::string16>* suggestions,
- std::vector<base::string16>* realms,
- bool show_all) {
- if (show_all ||
- StartsWith(fill_data.basic_data.fields[0].value, input, false)) {
- suggestions->push_back(fill_data.basic_data.fields[0].value);
- realms->push_back(base::UTF8ToUTF16(fill_data.preferred_realm));
- }
-
- for (PasswordFormFillData::LoginCollection::const_iterator iter =
- fill_data.additional_logins.begin();
- iter != fill_data.additional_logins.end();
- ++iter) {
- if (show_all || StartsWith(iter->first, input, false)) {
- suggestions->push_back(iter->first);
- realms->push_back(base::UTF8ToUTF16(iter->second.realm));
- }
- }
-
- 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 (show_all || StartsWith(iter->second[i], input, false)) {
- usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN;
- suggestions->push_back(iter->second[i]);
- realms->push_back(base::UTF8ToUTF16(iter->first.realm));
- }
- }
- }
-}
-
bool PasswordAutofillAgent::ShowSuggestionPopup(
const PasswordFormFillData& fill_data,
const blink::WebInputElement& user_input,
@@ -917,8 +1073,10 @@ bool PasswordAutofillAgent::ShowSuggestionPopup(
std::vector<base::string16> suggestions;
std::vector<base::string16> realms;
- GetSuggestions(
- fill_data, user_input.value(), &suggestions, &realms, show_all);
+ if (GetSuggestions(
+ fill_data, user_input.value(), &suggestions, &realms, show_all))
+ usernames_usage_ = OTHER_POSSIBLE_USERNAME_SHOWN;
+
DCHECK_EQ(suggestions.size(), realms.size());
FormData form;
@@ -939,133 +1097,6 @@ bool PasswordAutofillAgent::ShowSuggestionPopup(
return !suggestions.empty();
}
-void PasswordAutofillAgent::FillFormOnPasswordRecieved(
- const PasswordFormFillData& fill_data,
- blink::WebInputElement username_element,
- blink::WebInputElement password_element) {
- // Do not fill if the password field is in an iframe.
- DCHECK(password_element.document().frame());
- if (password_element.document().frame()->parent())
- return;
-
- bool form_contains_username_field = FillDataContainsUsername(fill_data);
- if (!ShouldIgnoreAutocompleteOffForPasswordFields() &&
- form_contains_username_field && !username_element.form().autoComplete())
- return;
-
- // If we can't modify the password, don't try to set the username
- if (!IsElementAutocompletable(password_element))
- return;
-
- // Try to set the username to the preferred name, but only if the field
- // can be set and isn't prefilled.
- 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);
- }
-
- // 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(
- blink::WebInputElement* username_element,
- blink::WebInputElement* password_element,
- const PasswordFormFillData& fill_data,
- bool exact_username_match,
- bool set_selection) {
- // Don't fill username if password can't be set.
- if (!IsElementAutocompletable(*password_element))
- return false;
-
- base::string16 current_username;
- if (!username_element->isNull()) {
- current_username = username_element->value();
- }
-
- // username and password will contain the match found if any.
- base::string16 username;
- base::string16 password;
-
- // 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) {
- 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 (password.empty())
- return false; // No match was found.
-
- // TODO(tkent): Check maxlength and pattern for both username and password
- // fields.
-
- // Input matches the username, fill in required values.
- if (!username_element->isNull() &&
- IsElementAutocompletable(*username_element)) {
- username_element->setValue(username, true);
- username_element->setAutofilled(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;
- }
-
- // Wait to fill in the password until a user gesture occurs. This is to make
- // sure that we do not fill in the DOM with a password until we believe the
- // user is intentionally interacting with the page.
- password_element->setSuggestedValue(password);
- gatekeeper_.RegisterElement(password_element);
-
- password_element->setAutofilled(true);
- return true;
-}
-
void PasswordAutofillAgent::PerformInlineAutocomplete(
const blink::WebInputElement& username_input,
const blink::WebInputElement& password_input,
@@ -1089,11 +1120,16 @@ 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 /* exact_username_match */,
- true /* set_selection */);
+ if (FillUserNameAndPassword(
+ &username,
+ &password,
+ fill_data,
+ false /* exact_username_match */,
+ true /* set_selection */,
+ base::Bind(&PasswordValueGatekeeper::RegisterElement,
+ base::Unretained(&gatekeeper_))))
+ usernames_usage_ = OTHER_POSSIBLE_USERNAME_SELECTED;
+
#endif
}
« no previous file with comments | « components/autofill/content/renderer/password_autofill_agent.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698