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

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

Issue 12434004: Move remaining Autofill code to //components/autofill. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix long lines Created 7 years, 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "base/utf_string_conversions.h"
6 #include "chrome/browser/autofill/autocomplete_history_manager.h"
7 #include "chrome/browser/autofill/autofill_external_delegate.h"
8 #include "chrome/browser/autofill/autofill_manager.h"
9 #include "components/autofill/common/autofill_messages.h"
10 #include "content/public/browser/navigation_controller.h"
11 #include "content/public/browser/notification_service.h"
12 #include "content/public/browser/notification_source.h"
13 #include "content/public/browser/notification_types.h"
14 #include "content/public/browser/render_view_host.h"
15 #include "content/public/browser/web_contents.h"
16 #include "grit/chromium_strings.h"
17 #include "grit/generated_resources.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/WebAutofillClient.h"
19 #include "ui/base/l10n/l10n_util.h"
20
21 #if defined(OS_ANDROID)
22 #include "content/public/browser/android/content_view_core.h"
23 #endif
24
25 using content::RenderViewHost;
26 using WebKit::WebAutofillClient;
27
28 DEFINE_WEB_CONTENTS_USER_DATA_KEY(AutofillExternalDelegate);
29
30 void AutofillExternalDelegate::CreateForWebContentsAndManager(
31 content::WebContents* web_contents,
32 AutofillManager* autofill_manager) {
33 if (FromWebContents(web_contents))
34 return;
35
36 web_contents->SetUserData(
37 UserDataKey(),
38 new AutofillExternalDelegate(web_contents, autofill_manager));
39 }
40
41 AutofillExternalDelegate::AutofillExternalDelegate(
42 content::WebContents* web_contents,
43 AutofillManager* autofill_manager)
44 : web_contents_(web_contents),
45 autofill_manager_(autofill_manager),
46 password_autofill_manager_(web_contents),
47 autofill_query_id_(0),
48 display_warning_if_disabled_(false),
49 has_autofill_suggestion_(false),
50 has_shown_autofill_popup_for_current_edit_(false),
51 registered_keyboard_listener_with_(NULL) {
52 DCHECK(autofill_manager);
53
54 registrar_.Add(this,
55 content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED,
56 content::Source<content::WebContents>(web_contents));
57 registrar_.Add(
58 this,
59 content::NOTIFICATION_NAV_ENTRY_COMMITTED,
60 content::Source<content::NavigationController>(
61 &(web_contents->GetController())));
62 }
63
64 AutofillExternalDelegate::~AutofillExternalDelegate() {}
65
66 void AutofillExternalDelegate::OnQuery(int query_id,
67 const FormData& form,
68 const FormFieldData& field,
69 const gfx::RectF& element_bounds,
70 bool display_warning_if_disabled) {
71 autofill_query_form_ = form;
72 autofill_query_field_ = field;
73 display_warning_if_disabled_ = display_warning_if_disabled;
74 autofill_query_id_ = query_id;
75 element_bounds_ = element_bounds;
76 }
77
78 void AutofillExternalDelegate::OnSuggestionsReturned(
79 int query_id,
80 const std::vector<string16>& autofill_values,
81 const std::vector<string16>& autofill_labels,
82 const std::vector<string16>& autofill_icons,
83 const std::vector<int>& autofill_unique_ids) {
84 if (query_id != autofill_query_id_)
85 return;
86
87 std::vector<string16> values(autofill_values);
88 std::vector<string16> labels(autofill_labels);
89 std::vector<string16> icons(autofill_icons);
90 std::vector<int> ids(autofill_unique_ids);
91
92 // Add a separator to go between the values and menu items.
93 values.push_back(string16());
94 labels.push_back(string16());
95 icons.push_back(string16());
96 ids.push_back(WebAutofillClient::MenuItemIDSeparator);
97
98 ApplyAutofillWarnings(&values, &labels, &icons, &ids);
99
100 // Only include "Autofill Options" special menu item if we have Autofill
101 // suggestions.
102 has_autofill_suggestion_ = false;
103 for (size_t i = 0; i < ids.size(); ++i) {
104 if (ids[i] > 0) {
105 has_autofill_suggestion_ = true;
106 break;
107 }
108 }
109
110 if (has_autofill_suggestion_)
111 ApplyAutofillOptions(&values, &labels, &icons, &ids);
112
113 // Remove the separator if it is the last element.
114 if (ids.back() == WebAutofillClient::MenuItemIDSeparator) {
115 values.pop_back();
116 labels.pop_back();
117 icons.pop_back();
118 ids.pop_back();
119 }
120
121 InsertDataListValues(&values, &labels, &icons, &ids);
122
123 if (values.empty()) {
124 // No suggestions, any popup currently showing is obsolete.
125 autofill_manager_->delegate()->HideAutofillPopup();
126 return;
127 }
128
129 // Send to display.
130 if (autofill_query_field_.is_focusable) {
131 autofill_manager_->delegate()->ShowAutofillPopup(
132 element_bounds_, values, labels, icons, ids, this);
133 }
134 }
135
136 void AutofillExternalDelegate::OnShowPasswordSuggestions(
137 const std::vector<string16>& suggestions,
138 const FormFieldData& field,
139 const gfx::RectF& element_bounds) {
140 autofill_query_field_ = field;
141 element_bounds_ = element_bounds;
142
143 if (suggestions.empty()) {
144 autofill_manager_->delegate()->HideAutofillPopup();
145 return;
146 }
147
148 std::vector<string16> empty(suggestions.size());
149 std::vector<int> password_ids(suggestions.size(),
150 WebAutofillClient::MenuItemIDPasswordEntry);
151 autofill_manager_->delegate()->ShowAutofillPopup(
152 element_bounds_, suggestions, empty, empty, password_ids, this);
153 }
154
155 void AutofillExternalDelegate::SetCurrentDataListValues(
156 const std::vector<string16>& data_list_values,
157 const std::vector<string16>& data_list_labels,
158 const std::vector<string16>& data_list_icons,
159 const std::vector<int>& data_list_unique_ids) {
160 data_list_values_ = data_list_values;
161 data_list_labels_ = data_list_labels;
162 data_list_icons_ = data_list_icons;
163 data_list_unique_ids_ = data_list_unique_ids;
164 }
165
166 void AutofillExternalDelegate::OnPopupShown(
167 content::KeyboardListener* listener) {
168 if (!registered_keyboard_listener_with_) {
169 registered_keyboard_listener_with_ = web_contents_->GetRenderViewHost();
170 registered_keyboard_listener_with_->AddKeyboardListener(listener);
171 }
172
173 autofill_manager_->OnDidShowAutofillSuggestions(
174 has_autofill_suggestion_ && !has_shown_autofill_popup_for_current_edit_);
175 has_shown_autofill_popup_for_current_edit_ |= has_autofill_suggestion_;
176 }
177
178 void AutofillExternalDelegate::OnPopupHidden(
179 content::KeyboardListener* listener) {
180 if (registered_keyboard_listener_with_ == web_contents_->GetRenderViewHost())
181 web_contents_->GetRenderViewHost()->RemoveKeyboardListener(listener);
182
183 registered_keyboard_listener_with_ = NULL;
184 }
185
186 void AutofillExternalDelegate::DidSelectSuggestion(int identifier) {
187 ClearPreviewedForm();
188
189 // Only preview the data if it is a profile.
190 if (identifier > 0)
191 FillAutofillFormData(identifier, true);
192 }
193
194 void AutofillExternalDelegate::DidAcceptSuggestion(const string16& value,
195 int identifier) {
196 RenderViewHost* host = web_contents_->GetRenderViewHost();
197
198 if (identifier == WebAutofillClient::MenuItemIDAutofillOptions) {
199 // User selected 'Autofill Options'.
200 autofill_manager_->OnShowAutofillDialog();
201 } else if (identifier == WebAutofillClient::MenuItemIDClearForm) {
202 // User selected 'Clear form'.
203 host->Send(new AutofillMsg_ClearForm(host->GetRoutingID()));
204 } else if (identifier == WebAutofillClient::MenuItemIDPasswordEntry &&
205 password_autofill_manager_.DidAcceptAutofillSuggestion(
206 autofill_query_field_, value)) {
207 // DidAcceptAutofillSuggestion has already handled the work to fill in
208 // the page as required.
209 } else if (identifier == WebAutofillClient::MenuItemIDDataListEntry) {
210 host->Send(new AutofillMsg_AcceptDataListSuggestion(host->GetRoutingID(),
211 value));
212 } else if (identifier == WebAutofillClient::MenuItemIDAutocompleteEntry) {
213 // User selected an Autocomplete, so we fill directly.
214 host->Send(new AutofillMsg_SetNodeText(host->GetRoutingID(), value));
215 } else {
216 FillAutofillFormData(identifier, false);
217 }
218
219 autofill_manager_->delegate()->HideAutofillPopup();
220 }
221
222 void AutofillExternalDelegate::RemoveSuggestion(const string16& value,
223 int identifier) {
224 if (identifier > 0) {
225 autofill_manager_->RemoveAutofillProfileOrCreditCard(identifier);
226 } else {
227 autofill_manager_->RemoveAutocompleteEntry(autofill_query_field_.name,
228 value);
229 }
230 }
231
232 void AutofillExternalDelegate::DidEndTextFieldEditing() {
233 autofill_manager_->delegate()->HideAutofillPopup();
234
235 has_shown_autofill_popup_for_current_edit_ = false;
236 }
237
238 void AutofillExternalDelegate::ClearPreviewedForm() {
239 RenderViewHost* host = web_contents_->GetRenderViewHost();
240 if (host)
241 host->Send(new AutofillMsg_ClearPreviewedForm(host->GetRoutingID()));
242 }
243
244 void AutofillExternalDelegate::Reset() {
245 autofill_manager_->delegate()->HideAutofillPopup();
246
247 password_autofill_manager_.Reset();
248 }
249
250 void AutofillExternalDelegate::AddPasswordFormMapping(
251 const FormFieldData& form,
252 const PasswordFormFillData& fill_data) {
253 password_autofill_manager_.AddPasswordFormMapping(form, fill_data);
254 }
255
256 void AutofillExternalDelegate::FillAutofillFormData(int unique_id,
257 bool is_preview) {
258 // If the selected element is a warning we don't want to do anything.
259 if (unique_id == WebAutofillClient::MenuItemIDWarningMessage)
260 return;
261
262 RenderViewHost* host = web_contents_->GetRenderViewHost();
263
264 if (is_preview) {
265 host->Send(new AutofillMsg_SetAutofillActionPreview(
266 host->GetRoutingID()));
267 } else {
268 host->Send(new AutofillMsg_SetAutofillActionFill(
269 host->GetRoutingID()));
270 }
271
272 // Fill the values for the whole form.
273 autofill_manager_->OnFillAutofillFormData(autofill_query_id_,
274 autofill_query_form_,
275 autofill_query_field_,
276 unique_id);
277 }
278
279 void AutofillExternalDelegate::ApplyAutofillWarnings(
280 std::vector<string16>* autofill_values,
281 std::vector<string16>* autofill_labels,
282 std::vector<string16>* autofill_icons,
283 std::vector<int>* autofill_unique_ids) {
284 if (!autofill_query_field_.should_autocomplete) {
285 // If autofill is disabled and we had suggestions, show a warning instead.
286 autofill_values->assign(
287 1, l10n_util::GetStringUTF16(IDS_AUTOFILL_WARNING_FORM_DISABLED));
288 autofill_labels->assign(1, string16());
289 autofill_icons->assign(1, string16());
290 autofill_unique_ids->assign(1, WebAutofillClient::MenuItemIDWarningMessage);
291 } else if (autofill_unique_ids->size() > 1 &&
292 (*autofill_unique_ids)[0] ==
293 WebAutofillClient::MenuItemIDWarningMessage) {
294 // If we received a warning instead of suggestions from autofill but regular
295 // suggestions from autocomplete, don't show the autofill warning.
296 autofill_values->erase(autofill_values->begin());
297 autofill_labels->erase(autofill_labels->begin());
298 autofill_icons->erase(autofill_icons->begin());
299 autofill_unique_ids->erase(autofill_unique_ids->begin());
300 }
301
302 // If we were about to show a warning and we shouldn't, don't.
303 if (!autofill_unique_ids->empty() &&
304 (*autofill_unique_ids)[0] ==
305 WebAutofillClient::MenuItemIDWarningMessage &&
306 !display_warning_if_disabled_) {
307 autofill_values->clear();
308 autofill_labels->clear();
309 autofill_icons->clear();
310 autofill_unique_ids->clear();
311 }
312 }
313
314 void AutofillExternalDelegate::ApplyAutofillOptions(
315 std::vector<string16>* autofill_values,
316 std::vector<string16>* autofill_labels,
317 std::vector<string16>* autofill_icons,
318 std::vector<int>* autofill_unique_ids) {
319 // The form has been auto-filled, so give the user the chance to clear the
320 // form. Append the 'Clear form' menu item.
321 if (autofill_query_field_.is_autofilled) {
322 autofill_values->push_back(
323 l10n_util::GetStringUTF16(IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM));
324 autofill_labels->push_back(string16());
325 autofill_icons->push_back(string16());
326 autofill_unique_ids->push_back(WebAutofillClient::MenuItemIDClearForm);
327 }
328
329 // Append the 'Chrome Autofill options' menu item;
330 autofill_values->push_back(
331 l10n_util::GetStringUTF16(IDS_AUTOFILL_OPTIONS_POPUP));
332 autofill_labels->push_back(string16());
333 autofill_icons->push_back(string16());
334 autofill_unique_ids->push_back(WebAutofillClient::MenuItemIDAutofillOptions);
335 }
336
337 void AutofillExternalDelegate::InsertDataListValues(
338 std::vector<string16>* autofill_values,
339 std::vector<string16>* autofill_labels,
340 std::vector<string16>* autofill_icons,
341 std::vector<int>* autofill_unique_ids) {
342 if (data_list_values_.empty())
343 return;
344
345 // Insert the separator between the datalist and Autofill values (if there
346 // are any).
347 if (!autofill_values->empty()) {
348 autofill_values->insert(autofill_values->begin(), string16());
349 autofill_labels->insert(autofill_labels->begin(), string16());
350 autofill_icons->insert(autofill_icons->begin(), string16());
351 autofill_unique_ids->insert(autofill_unique_ids->begin(),
352 WebAutofillClient::MenuItemIDSeparator);
353 }
354
355 // Insert the datalist elements.
356 autofill_values->insert(autofill_values->begin(),
357 data_list_values_.begin(),
358 data_list_values_.end());
359 autofill_labels->insert(autofill_labels->begin(),
360 data_list_labels_.begin(),
361 data_list_labels_.end());
362 autofill_icons->insert(autofill_icons->begin(),
363 data_list_icons_.begin(),
364 data_list_icons_.end());
365 autofill_unique_ids->insert(autofill_unique_ids->begin(),
366 data_list_unique_ids_.begin(),
367 data_list_unique_ids_.end());
368 }
369
370 void AutofillExternalDelegate::Observe(
371 int type,
372 const content::NotificationSource& source,
373 const content::NotificationDetails& details) {
374 if (type == content::NOTIFICATION_WEB_CONTENTS_VISIBILITY_CHANGED) {
375 if (!*content::Details<bool>(details).ptr())
376 autofill_manager_->delegate()->HideAutofillPopup();
377 } else if (type == content::NOTIFICATION_NAV_ENTRY_COMMITTED) {
378 autofill_manager_->delegate()->HideAutofillPopup();
379 } else {
380 NOTREACHED();
381 }
382 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698