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

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

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

Powered by Google App Engine
This is Rietveld 408576698