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

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

Powered by Google App Engine
This is Rietveld 408576698