Commit 580c3805 authored by jww@chromium.org's avatar jww@chromium.org

Add password manager autocomplete suggestion when a username element in clicked.

This adds a full credential selection whenever a username element is clicked. Previously, if a username element was filled by either the user or the password manager, the user would have to erase the entire field to see the full list of credentials the user has. Now the user can click on the field at any point to get a full list of accounts. However, if the user starts typing again, then inline autocomplete takes over.

BUG=341474

Review URL: https://codereview.chromium.org/166043006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@283383 0039d316-1c4b-4281-b951-d872f2087c98
parent 925e4e74
......@@ -318,8 +318,15 @@ void AutofillAgent::FormControlElementClicked(
if (!input_element && !IsTextAreaElement(element))
return;
if (was_focused)
ShowSuggestions(element, true, false, true, false);
bool show_full_suggestion_list = element.isAutofilled() || was_focused;
bool show_password_suggestions_only = !was_focused;
ShowSuggestions(element,
true,
false,
true,
false,
show_full_suggestion_list,
show_password_suggestions_only);
}
void AutofillAgent::FormControlElementLostFocus() {
......@@ -375,7 +382,7 @@ void AutofillAgent::TextFieldDidChangeImpl(
}
}
ShowSuggestions(element, false, true, false, false);
ShowSuggestions(element, false, true, false, false, false, false);
FormData form;
FormFieldData field;
......@@ -397,11 +404,11 @@ void AutofillAgent::textFieldDidReceiveKeyDown(const WebInputElement& element,
if (event.windowsKeyCode == ui::VKEY_DOWN ||
event.windowsKeyCode == ui::VKEY_UP)
ShowSuggestions(element, true, true, true, false);
ShowSuggestions(element, true, true, true, false, false, false);
}
void AutofillAgent::openTextDataListChooser(const WebInputElement& element) {
ShowSuggestions(element, true, false, false, true);
ShowSuggestions(element, true, false, false, true, false, false);
}
void AutofillAgent::firstUserGestureObserved() {
......@@ -553,9 +560,13 @@ void AutofillAgent::ShowSuggestions(const WebFormControlElement& element,
bool autofill_on_empty_values,
bool requires_caret_at_end,
bool display_warning_if_disabled,
bool datalist_only) {
bool datalist_only,
bool show_full_suggestion_list,
bool show_password_suggestions_only) {
if (!element.isEnabled() || element.isReadOnly())
return;
if (!datalist_only && !element.suggestedValue().isEmpty())
return;
const WebInputElement* input_element = toWebInputElement(&element);
if (input_element) {
......@@ -584,8 +595,10 @@ void AutofillAgent::ShowSuggestions(const WebFormControlElement& element,
}
element_ = element;
if (input_element &&
password_autofill_agent_->ShowSuggestions(*input_element)) {
if (IsAutofillableInputElement(input_element) &&
(password_autofill_agent_->ShowSuggestions(*input_element,
show_full_suggestion_list) ||
show_password_suggestions_only)) {
is_popup_possibly_visible_ = true;
return;
}
......
......@@ -141,11 +141,18 @@ class AutofillAgent : public content::RenderViewObserver,
// |datalist_only| specifies whether all of <datalist> suggestions and no
// autofill suggestions are shown. |autofill_on_empty_values| and
// |requires_caret_at_end| are ignored if |datalist_only| is true.
// |show_full_suggestion_list| specifies that all autofill suggestions should
// be shown and none should be elided because of the current value of
// |element| (relevant for inline autocomplete).
// |show_password_suggestions_only| specifies that only show a suggestions box
// if |element| is part of a password form, otherwise show no suggestions.
void ShowSuggestions(const blink::WebFormControlElement& element,
bool autofill_on_empty_values,
bool requires_caret_at_end,
bool display_warning_if_disabled,
bool datalist_only);
bool datalist_only,
bool show_full_suggestion_list,
bool show_password_suggestions_only);
// Queries the browser for Autocomplete and Autofill suggestions for the given
// |element|.
......@@ -245,6 +252,7 @@ class AutofillAgent : public content::RenderViewObserver,
FRIEND_TEST_ALL_PREFIXES(
PasswordAutofillAgentTest,
PasswordAutofillTriggersOnChangeEventsWaitForUsername);
FRIEND_TEST_ALL_PREFIXES(PasswordAutofillAgentTest, CredentialsOnClick);
FRIEND_TEST_ALL_PREFIXES(RequestAutocompleteRendererTest,
NoCancelOnMainFrameNavigateAfterDone);
FRIEND_TEST_ALL_PREFIXES(RequestAutocompleteRendererTest,
......
......@@ -337,7 +337,7 @@ bool PasswordAutofillAgent::TextDidChangeInTextField(
// But refresh the popup. Note, since this is ours, return true to signal
// no further processing is required.
if (iter->second.backspace_pressed_last) {
ShowSuggestionPopup(iter->second.fill_data, username);
ShowSuggestionPopup(iter->second.fill_data, username, false);
return true;
}
......@@ -435,7 +435,8 @@ bool PasswordAutofillAgent::DidClearAutofillSelection(
}
bool PasswordAutofillAgent::ShowSuggestions(
const blink::WebInputElement& element) {
const blink::WebInputElement& element,
bool show_all) {
LoginToPasswordInfoMap::const_iterator iter =
login_to_password_info_.find(element);
if (iter == login_to_password_info_.end())
......@@ -449,7 +450,7 @@ bool PasswordAutofillAgent::ShowSuggestions(
!IsElementAutocompletable(iter->second.password_field))
return true;
return ShowSuggestionPopup(iter->second.fill_data, element);
return ShowSuggestionPopup(iter->second.fill_data, element, show_all);
}
bool PasswordAutofillAgent::OriginCanAccessPasswordManager(
......@@ -810,8 +811,10 @@ void PasswordAutofillAgent::GetSuggestions(
const PasswordFormFillData& fill_data,
const base::string16& input,
std::vector<base::string16>* suggestions,
std::vector<base::string16>* realms) {
if (StartsWith(fill_data.basic_data.fields[0].value, input, false)) {
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));
}
......@@ -820,7 +823,7 @@ void PasswordAutofillAgent::GetSuggestions(
fill_data.additional_logins.begin();
iter != fill_data.additional_logins.end();
++iter) {
if (StartsWith(iter->first, input, false)) {
if (show_all || StartsWith(iter->first, input, false)) {
suggestions->push_back(iter->first);
realms->push_back(base::UTF8ToUTF16(iter->second.realm));
}
......@@ -831,7 +834,7 @@ void PasswordAutofillAgent::GetSuggestions(
iter != fill_data.other_possible_usernames.end();
++iter) {
for (size_t i = 0; i < iter->second.size(); ++i) {
if (StartsWith(iter->second[i], input, false)) {
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));
......@@ -842,7 +845,8 @@ void PasswordAutofillAgent::GetSuggestions(
bool PasswordAutofillAgent::ShowSuggestionPopup(
const PasswordFormFillData& fill_data,
const blink::WebInputElement& user_input) {
const blink::WebInputElement& user_input,
bool show_all) {
blink::WebFrame* frame = user_input.document().frame();
if (!frame)
return false;
......@@ -853,7 +857,8 @@ bool PasswordAutofillAgent::ShowSuggestionPopup(
std::vector<base::string16> suggestions;
std::vector<base::string16> realms;
GetSuggestions(fill_data, user_input.value(), &suggestions, &realms);
GetSuggestions(
fill_data, user_input.value(), &suggestions, &realms, show_all);
DCHECK_EQ(suggestions.size(), realms.size());
FormData form;
......@@ -1013,7 +1018,7 @@ void PasswordAutofillAgent::PerformInlineAutocomplete(
}
// Show the popup with the list of available usernames.
ShowSuggestionPopup(fill_data, username);
ShowSuggestionPopup(fill_data, username, false);
#if !defined(OS_ANDROID)
// Fill the user and password field with the most relevant match. Android
......
......@@ -54,9 +54,11 @@ class PasswordAutofillAgent : public content::RenderViewObserver {
// their previous filled state. Return false if no login information was
// found for the form.
bool DidClearAutofillSelection(const blink::WebNode& node);
// Shows an Autofill popup with username suggestions for |element|.
// Shows an Autofill popup with username suggestions for |element|. If
// |show_all| is |true|, will show all possible suggestions for that element,
// otherwise shows suggestions based on current value of |element|.
// Returns true if any suggestions were shown, false otherwise.
bool ShowSuggestions(const blink::WebInputElement& element);
bool ShowSuggestions(const blink::WebInputElement& element, bool show_all);
// Called when new form controls are inserted.
void OnDynamicFormsSeen(blink::WebFrame* frame);
......@@ -146,10 +148,12 @@ class PasswordAutofillAgent : public content::RenderViewObserver {
void GetSuggestions(const PasswordFormFillData& fill_data,
const base::string16& input,
std::vector<base::string16>* suggestions,
std::vector<base::string16>* realms);
std::vector<base::string16>* realms,
bool show_all);
bool ShowSuggestionPopup(const PasswordFormFillData& fill_data,
const blink::WebInputElement& user_input);
const blink::WebInputElement& user_input,
bool show_all);
// Attempts to fill |username_element| and |password_element| with the
// |fill_data|. Will use the data corresponding to the preferred username,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment