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

Side by Side Diff: chrome/browser/autofill/autofill_external_delegate.cc

Issue 10443084: Add Datalist Support to New Autofill UI (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Merging Created 8 years, 6 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/utf_string_conversions.h" 5 #include "base/utf_string_conversions.h"
6 #include "chrome/browser/autocomplete_history_manager.h" 6 #include "chrome/browser/autocomplete_history_manager.h"
7 #include "chrome/browser/autofill/autofill_external_delegate.h" 7 #include "chrome/browser/autofill/autofill_external_delegate.h"
8 #include "chrome/browser/autofill/autofill_manager.h" 8 #include "chrome/browser/autofill/autofill_manager.h"
9 #include "chrome/common/autofill_messages.h" 9 #include "chrome/common/autofill_messages.h"
10 #include "chrome/common/chrome_constants.h" 10 #include "chrome/common/chrome_constants.h"
(...skipping 12 matching lines...) Expand all
23 23
24 AutofillExternalDelegate::AutofillExternalDelegate( 24 AutofillExternalDelegate::AutofillExternalDelegate(
25 TabContents* tab_contents, 25 TabContents* tab_contents,
26 AutofillManager* autofill_manager) 26 AutofillManager* autofill_manager)
27 : tab_contents_(tab_contents), 27 : tab_contents_(tab_contents),
28 autofill_manager_(autofill_manager), 28 autofill_manager_(autofill_manager),
29 password_autofill_manager_( 29 password_autofill_manager_(
30 tab_contents ? tab_contents->web_contents() : NULL), 30 tab_contents ? tab_contents->web_contents() : NULL),
31 autofill_query_id_(0), 31 autofill_query_id_(0),
32 display_warning_if_disabled_(false), 32 display_warning_if_disabled_(false),
33 has_shown_autofill_popup_for_current_edit_(false) { 33 has_shown_autofill_popup_for_current_edit_(false),
34 popup_visible_(false) {
34 } 35 }
35 36
36 void AutofillExternalDelegate::SelectAutofillSuggestionAtIndex(int unique_id) { 37 void AutofillExternalDelegate::SelectAutofillSuggestionAtIndex(int unique_id) {
37 if (unique_id == WebAutofillClient::MenuItemIDAutofillOptions ||
38 unique_id == WebAutofillClient::MenuItemIDClearForm ||
39 unique_id == WebAutofillClient::MenuItemIDSeparator ||
40 unique_id == WebAutofillClient::MenuItemIDWarningMessage)
41 return;
42
43 ClearPreviewedForm(); 38 ClearPreviewedForm();
44 39
45 if (unique_id == WebAutofillClient::MenuItemIDPasswordEntry) 40 // Only preview the data if it is a profile.
46 return; 41 if (unique_id > 0)
47 42 FillAutofillFormData(unique_id, true);
48 FillAutofillFormData(unique_id, true);
49 } 43 }
50 44
51 void AutofillExternalDelegate::OnQuery(int query_id, 45 void AutofillExternalDelegate::OnQuery(int query_id,
52 const webkit::forms::FormData& form, 46 const webkit::forms::FormData& form,
53 const webkit::forms::FormField& field, 47 const webkit::forms::FormField& field,
54 const gfx::Rect& bounds, 48 const gfx::Rect& bounds,
55 bool display_warning_if_disabled) { 49 bool display_warning_if_disabled) {
56 autofill_query_form_ = form; 50 autofill_query_form_ = form;
57 autofill_query_field_ = field; 51 autofill_query_field_ = field;
58 display_warning_if_disabled_ = display_warning_if_disabled; 52 display_warning_if_disabled_ = display_warning_if_disabled;
59 autofill_query_id_ = query_id; 53 autofill_query_id_ = query_id;
60 54
61 OnQueryPlatformSpecific(query_id, form, field, bounds); 55 OnQueryPlatformSpecific(query_id, form, field, bounds);
62 } 56 }
63 57
64 void AutofillExternalDelegate::OnSuggestionsReturned( 58 void AutofillExternalDelegate::OnSuggestionsReturned(
65 int query_id, 59 int query_id,
66 const std::vector<string16>& values, 60 const std::vector<string16>& autofill_values,
67 const std::vector<string16>& labels, 61 const std::vector<string16>& autofill_labels,
68 const std::vector<string16>& icons, 62 const std::vector<string16>& autofill_icons,
69 const std::vector<int>& unique_ids) { 63 const std::vector<int>& autofill_unique_ids) {
70 if (query_id != autofill_query_id_) 64 if (query_id != autofill_query_id_)
71 return; 65 return;
72 66
73 if (values.empty()) { 67 std::vector<string16> values(autofill_values);
74 // No suggestions, any popup currently showing is obsolete. 68 std::vector<string16> labels(autofill_labels);
75 HideAutofillPopup(); 69 std::vector<string16> icons(autofill_icons);
76 return; 70 std::vector<int> ids(autofill_unique_ids);
77 }
78
79 std::vector<string16> v(values);
80 std::vector<string16> l(labels);
81 std::vector<string16> i(icons);
82 std::vector<int> ids(unique_ids);
83 71
84 // Add a separator to go between the values and menu items. 72 // Add a separator to go between the values and menu items.
85 v.push_back(string16()); 73 values.push_back(string16());
86 l.push_back(string16()); 74 labels.push_back(string16());
87 i.push_back(string16()); 75 icons.push_back(string16());
88 ids.push_back(WebAutofillClient::MenuItemIDSeparator); 76 ids.push_back(WebAutofillClient::MenuItemIDSeparator);
89 77
90 DCHECK_GT(ids.size(), 0U); 78 ApplyAutofillWarnings(&values, &labels, &icons, &ids);
91 if (!autofill_query_field_.should_autocomplete) {
92 // If autofill is disabled and we had suggestions, show a warning instead.
93 v.assign(1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED));
94 l.assign(1, string16());
95 i.assign(1, string16());
96 ids.assign(1, WebAutofillClient::MenuItemIDWarningMessage);
97 } else if (ids[0] < 0 && ids.size() > 1) {
98 // If we received a warning instead of suggestions from autofill but regular
99 // suggestions from autocomplete, don't show the autofill warning.
100 v.erase(v.begin());
101 l.erase(l.begin());
102 i.erase(i.begin());
103 ids.erase(ids.begin());
104 }
105
106 // If we were about to show a warning and we shouldn't, don't.
107 if (ids[0] < 0 && !display_warning_if_disabled_)
108 return;
109 79
110 // Only include "Autofill Options" special menu item if we have Autofill 80 // Only include "Autofill Options" special menu item if we have Autofill
111 // items, identified by |unique_ids| having at least one valid value. 81 // items, identified by |unique_ids| having at least one valid value.
112 bool has_autofill_item = false; 82 bool has_autofill_item = false;
113 for (size_t i = 0; i < ids.size(); ++i) { 83 for (size_t i = 0; i < ids.size(); ++i) {
114 if (ids[i] > 0) { 84 if (ids[i] > 0) {
115 has_autofill_item = true; 85 has_autofill_item = true;
116 break; 86 break;
117 } 87 }
118 } 88 }
119 89
120 // The form has been auto-filled, so give the user the chance to clear the 90 if (has_autofill_item)
121 // form. Append the 'Clear form' menu item. 91 ApplyAutofillOptions(&values, &labels, &icons, &ids);
122 if (has_autofill_item && autofill_query_field_.is_autofilled) {
123 v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM));
124 l.push_back(string16());
125 i.push_back(string16());
126 ids.push_back(WebAutofillClient::MenuItemIDClearForm);
127 }
128
129 if (has_autofill_item) {
130 // Append the 'Chrome Autofill options' menu item;
131 v.push_back(l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP));
132 l.push_back(string16());
133 i.push_back(string16());
134 ids.push_back(WebAutofillClient::MenuItemIDAutofillOptions);
135 }
136 92
137 // Remove the separator if it is the last element. 93 // Remove the separator if it is the last element.
138 if (*(ids.rbegin()) == WebAutofillClient::MenuItemIDSeparator) { 94 if (ids.back() == WebAutofillClient::MenuItemIDSeparator) {
139 v.pop_back(); 95 values.pop_back();
140 l.pop_back(); 96 labels.pop_back();
141 i.pop_back(); 97 icons.pop_back();
142 ids.pop_back(); 98 ids.pop_back();
143 } 99 }
144 100
101 InsertDataListValues(&values, &labels, &icons, &ids);
102
103 if (values.empty()) {
104 // No suggestions, any popup currently showing is obsolete.
105 HideAutofillPopup();
106 return;
107 }
108
145 // Send to display. 109 // Send to display.
146 if (!v.empty() && autofill_query_field_.is_focusable) 110 if (autofill_query_field_.is_focusable) {
147 ApplyAutofillSuggestions(v, l, i, ids); 111 popup_visible_ = true;
112 ApplyAutofillSuggestions(values, labels, icons, ids);
148 113
149 tab_contents_->autofill_manager()->OnDidShowAutofillSuggestions( 114 tab_contents_->autofill_manager()->OnDidShowAutofillSuggestions(
150 has_autofill_item && !has_shown_autofill_popup_for_current_edit_); 115 has_autofill_item && !has_shown_autofill_popup_for_current_edit_);
151 has_shown_autofill_popup_for_current_edit_ |= has_autofill_item; 116 has_shown_autofill_popup_for_current_edit_ |= has_autofill_item;
117 }
152 } 118 }
153 119
154 void AutofillExternalDelegate::OnShowPasswordSuggestions( 120 void AutofillExternalDelegate::OnShowPasswordSuggestions(
155 const std::vector<string16>& suggestions, 121 const std::vector<string16>& suggestions,
156 const webkit::forms::FormField& field, 122 const webkit::forms::FormField& field,
157 const gfx::Rect& bounds) { 123 const gfx::Rect& bounds) {
158 autofill_query_field_ = field; 124 autofill_query_field_ = field;
159 125
160 if (suggestions.empty()) { 126 if (suggestions.empty()) {
161 HideAutofillPopup(); 127 HideAutofillPopup();
162 return; 128 return;
163 } 129 }
164 130
165 SetBounds(bounds); 131 SetBounds(bounds);
166 132
167 std::vector<string16> empty(suggestions.size()); 133 std::vector<string16> empty(suggestions.size());
168 std::vector<int> password_ids(suggestions.size(), 134 std::vector<int> password_ids(suggestions.size(),
169 WebAutofillClient::MenuItemIDPasswordEntry); 135 WebAutofillClient::MenuItemIDPasswordEntry);
170 ApplyAutofillSuggestions(suggestions, empty, empty, password_ids); 136 ApplyAutofillSuggestions(suggestions, empty, empty, password_ids);
171 } 137 }
172 138
139 void AutofillExternalDelegate::SetCurrentDataListValues(
140 const std::vector<string16>& data_list_values,
141 const std::vector<string16>& data_list_labels,
142 const std::vector<string16>& data_list_icons,
143 const std::vector<int>& data_list_unique_ids) {
144 // TODO(csharp): Modify the code to allow the data list values to change
145 // even if the popup is visible.
146 // http://crbug.com/131003
147 if (!popup_visible_) {
148 data_list_values_ = data_list_values;
149 data_list_labels_ = data_list_labels;
150 data_list_icons_ = data_list_icons;
151 data_list_unique_ids_ = data_list_unique_ids;
152 }
153 }
154
173 void AutofillExternalDelegate::RemoveAutocompleteEntry(const string16& value) { 155 void AutofillExternalDelegate::RemoveAutocompleteEntry(const string16& value) {
174 if (tab_contents_) { 156 if (tab_contents_) {
175 tab_contents_->autocomplete_history_manager()-> 157 tab_contents_->autocomplete_history_manager()->
176 OnRemoveAutocompleteEntry(autofill_query_field_.name, value); 158 OnRemoveAutocompleteEntry(autofill_query_field_.name, value);
177 } 159 }
178 } 160 }
179 161
180 void AutofillExternalDelegate::RemoveAutofillProfileOrCreditCard( 162 void AutofillExternalDelegate::RemoveAutofillProfileOrCreditCard(
181 int unique_id) { 163 int unique_id) {
182 autofill_manager_->RemoveAutofillProfileOrCreditCard(unique_id); 164 autofill_manager_->RemoveAutofillProfileOrCreditCard(unique_id);
183 } 165 }
184 166
185 167
186 void AutofillExternalDelegate::DidEndTextFieldEditing() { 168 void AutofillExternalDelegate::DidEndTextFieldEditing() {
187 HideAutofillPopup(); 169 HideAutofillPopup();
188 170
189 has_shown_autofill_popup_for_current_edit_ = false; 171 has_shown_autofill_popup_for_current_edit_ = false;
190 } 172 }
191 173
192 bool AutofillExternalDelegate::DidAcceptAutofillSuggestions( 174 bool AutofillExternalDelegate::DidAcceptAutofillSuggestions(
193 const string16& value, 175 const string16& value,
194 int unique_id, 176 int unique_id,
195 unsigned index) { 177 unsigned index) {
196 // If the selected element is a warning we don't want to do anything. 178 // If the selected element is a warning we don't want to do anything.
197 if (unique_id == WebAutofillClient::MenuItemIDWarningMessage) 179 if (unique_id == WebAutofillClient::MenuItemIDWarningMessage)
198 return false; 180 return false;
199 181
182 RenderViewHost* host =
183 tab_contents_->web_contents()->GetRenderViewHost();
184
200 if (unique_id == WebAutofillClient::MenuItemIDAutofillOptions) { 185 if (unique_id == WebAutofillClient::MenuItemIDAutofillOptions) {
201 // User selected 'Autofill Options'. 186 // User selected 'Autofill Options'.
202 autofill_manager_->OnShowAutofillDialog(); 187 autofill_manager_->OnShowAutofillDialog();
203 } else if (unique_id == WebAutofillClient::MenuItemIDClearForm) { 188 } else if (unique_id == WebAutofillClient::MenuItemIDClearForm) {
204 // User selected 'Clear form'. 189 // User selected 'Clear form'.
205 RenderViewHost* host = tab_contents_->web_contents()->GetRenderViewHost();
206 host->Send(new AutofillMsg_ClearForm(host->GetRoutingID())); 190 host->Send(new AutofillMsg_ClearForm(host->GetRoutingID()));
207 } else if (unique_id == WebAutofillClient::MenuItemIDPasswordEntry && 191 } else if (unique_id == WebAutofillClient::MenuItemIDPasswordEntry &&
208 password_autofill_manager_.DidAcceptAutofillSuggestion( 192 password_autofill_manager_.DidAcceptAutofillSuggestion(
209 autofill_query_field_, value)) { 193 autofill_query_field_, value)) {
210 // DidAcceptAutofillSuggestion has already handled the work to fill in 194 // DidAcceptAutofillSuggestion has already handled the work to fill in
211 // the page as required. 195 // the page as required.
196 } else if (unique_id == WebAutofillClient::MenuItemIDDataListEntry) {
197 host->Send(new AutofillMsg_AcceptDataListSuggestion(host->GetRoutingID(),
198 value));
212 } else if (unique_id == WebAutofillClient::MenuItemIDAutocompleteEntry) { 199 } else if (unique_id == WebAutofillClient::MenuItemIDAutocompleteEntry) {
213 // User selected an Autocomplete, so we fill directly. 200 // User selected an Autocomplete, so we fill directly.
214 RenderViewHost* host = tab_contents_->web_contents()->GetRenderViewHost();
215 host->Send(new AutofillMsg_SetNodeText( 201 host->Send(new AutofillMsg_SetNodeText(
216 host->GetRoutingID(), 202 host->GetRoutingID(),
217 value)); 203 value));
218 } else { 204 } else {
219 FillAutofillFormData(unique_id, false); 205 FillAutofillFormData(unique_id, false);
220 } 206 }
221 207
222 HideAutofillPopup(); 208 HideAutofillPopup();
223 209
224 return true; 210 return true;
225 } 211 }
226 212
227 void AutofillExternalDelegate::ClearPreviewedForm() { 213 void AutofillExternalDelegate::ClearPreviewedForm() {
228 RenderViewHost* host = tab_contents_->web_contents()->GetRenderViewHost(); 214 RenderViewHost* host = tab_contents_->web_contents()->GetRenderViewHost();
229 host->Send(new AutofillMsg_ClearPreviewedForm(host->GetRoutingID())); 215 host->Send(new AutofillMsg_ClearPreviewedForm(host->GetRoutingID()));
230 } 216 }
231 217
232 void AutofillExternalDelegate::HideAutofillPopup() { 218 void AutofillExternalDelegate::HideAutofillPopup() {
219 popup_visible_ = false;
220
233 HideAutofillPopupInternal(); 221 HideAutofillPopupInternal();
234 } 222 }
235 223
236 void AutofillExternalDelegate::Reset() { 224 void AutofillExternalDelegate::Reset() {
237 HideAutofillPopup(); 225 HideAutofillPopup();
238 226
239 password_autofill_manager_.Reset(); 227 password_autofill_manager_.Reset();
240 } 228 }
241 229
242 void AutofillExternalDelegate::AddPasswordFormMapping( 230 void AutofillExternalDelegate::AddPasswordFormMapping(
(...skipping 14 matching lines...) Expand all
257 host->GetRoutingID())); 245 host->GetRoutingID()));
258 } 246 }
259 247
260 // Fill the values for the whole form. 248 // Fill the values for the whole form.
261 autofill_manager_->OnFillAutofillFormData(autofill_query_id_, 249 autofill_manager_->OnFillAutofillFormData(autofill_query_id_,
262 autofill_query_form_, 250 autofill_query_form_,
263 autofill_query_field_, 251 autofill_query_field_,
264 unique_id); 252 unique_id);
265 } 253 }
266 254
255 void AutofillExternalDelegate::ApplyAutofillWarnings(
256 std::vector<string16>* autofill_values,
257 std::vector<string16>* autofill_labels,
258 std::vector<string16>* autofill_icons,
259 std::vector<int>* autofill_unique_ids) {
260 if (!autofill_query_field_.should_autocomplete) {
261 // If autofill is disabled and we had suggestions, show a warning instead.
262 autofill_values->assign(
263 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED));
264 autofill_labels->assign(1, string16());
265 autofill_icons->assign(1, string16());
266 autofill_unique_ids->assign(1, WebAutofillClient::MenuItemIDWarningMessage);
267 } else if (autofill_unique_ids->size() > 1 &&
268 (*autofill_unique_ids)[0] ==
269 WebAutofillClient::MenuItemIDWarningMessage) {
270 // If we received a warning instead of suggestions from autofill but regular
271 // suggestions from autocomplete, don't show the autofill warning.
272 autofill_values->erase(autofill_values->begin());
273 autofill_labels->erase(autofill_labels->begin());
274 autofill_icons->erase(autofill_icons->begin());
275 autofill_unique_ids->erase(autofill_unique_ids->begin());
276 }
277
278 // If we were about to show a warning and we shouldn't, don't.
279 if (!autofill_unique_ids->empty() &&
280 (*autofill_unique_ids)[0] ==
281 WebAutofillClient::MenuItemIDWarningMessage &&
282 !display_warning_if_disabled_) {
283 autofill_values->clear();
284 autofill_labels->clear();
285 autofill_icons->clear();
286 autofill_unique_ids->clear();
287 }
288 }
289
290 void AutofillExternalDelegate::ApplyAutofillOptions(
291 std::vector<string16>* autofill_values,
292 std::vector<string16>* autofill_labels,
293 std::vector<string16>* autofill_icons,
294 std::vector<int>* autofill_unique_ids) {
295 // The form has been auto-filled, so give the user the chance to clear the
296 // form. Append the 'Clear form' menu item.
297 if (autofill_query_field_.is_autofilled) {
298 autofill_values->push_back(
299 l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM));
300 autofill_labels->push_back(string16());
301 autofill_icons->push_back(string16());
302 autofill_unique_ids->push_back(WebAutofillClient::MenuItemIDClearForm);
303 }
304
305 // Append the 'Chrome Autofill options' menu item;
306 autofill_values->push_back(
307 l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP));
308 autofill_labels->push_back(string16());
309 autofill_icons->push_back(string16());
310 autofill_unique_ids->push_back(WebAutofillClient::MenuItemIDAutofillOptions);
311 }
312
313 void AutofillExternalDelegate::InsertDataListValues(
314 std::vector<string16>* autofill_values,
315 std::vector<string16>* autofill_labels,
316 std::vector<string16>* autofill_icons,
317 std::vector<int>* autofill_unique_ids) {
318 if (data_list_values_.empty())
319 return;
320
321 // Insert the separator between the datalist and Autofill values (if there
322 // are any).
323 if (!autofill_values->empty()) {
324 autofill_values->insert(autofill_values->begin(), string16());
325 autofill_labels->insert(autofill_labels->begin(), string16());
326 autofill_icons->insert(autofill_icons->begin(), string16());
327 autofill_unique_ids->insert(autofill_unique_ids->begin(),
328 WebAutofillClient::MenuItemIDSeparator);
329 }
330
331 // Insert the datalist elements.
332 autofill_values->insert(autofill_values->begin(),
333 data_list_values_.begin(),
334 data_list_values_.end());
335 autofill_labels->insert(autofill_labels->begin(),
336 data_list_labels_.begin(),
337 data_list_labels_.end());
338 autofill_icons->insert(autofill_icons->begin(),
339 data_list_icons_.begin(),
340 data_list_icons_.end());
341 autofill_unique_ids->insert(autofill_unique_ids->begin(),
342 data_list_unique_ids_.begin(),
343 data_list_unique_ids_.end());
344 }
345
267 // Add a "!defined(OS_YOUROS) for each platform that implements this 346 // Add a "!defined(OS_YOUROS) for each platform that implements this
268 // in an autofill_external_delegate_YOUROS.cc. Currently there are 347 // in an autofill_external_delegate_YOUROS.cc. Currently there are
269 // none, so all platforms use the default. 348 // none, so all platforms use the default.
270 349
271 #if !defined(OS_ANDROID) && !defined(TOOLKIT_GTK) 350 #if !defined(OS_ANDROID) && !defined(TOOLKIT_GTK)
272 351
273 AutofillExternalDelegate* AutofillExternalDelegate::Create( 352 AutofillExternalDelegate* AutofillExternalDelegate::Create(
274 TabContents*, AutofillManager*) { 353 TabContents*, AutofillManager*) {
275 return NULL; 354 return NULL;
276 } 355 }
277 356
278 #endif 357 #endif
OLDNEW
« no previous file with comments | « chrome/browser/autofill/autofill_external_delegate.h ('k') | chrome/browser/autofill/autofill_external_delegate_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698