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

Side by Side Diff: chrome/renderer/autofill/autofill_agent.cc

Issue 11270018: [autofill] Adding new API to request an interactive autocomplete UI flow. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review feedback Created 8 years, 1 month 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
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 "chrome/renderer/autofill/autofill_agent.h" 5 #include "chrome/renderer/autofill/autofill_agent.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/string_split.h" 10 #include "base/string_split.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 namespace { 47 namespace {
48 48
49 // The size above which we stop triggering autofill for an input text field 49 // The size above which we stop triggering autofill for an input text field
50 // (so to avoid sending long strings through IPC). 50 // (so to avoid sending long strings through IPC).
51 const size_t kMaximumTextSizeForAutofill = 1000; 51 const size_t kMaximumTextSizeForAutofill = 1000;
52 52
53 // The maximum number of data list elements to send to the browser process 53 // The maximum number of data list elements to send to the browser process
54 // via IPC (to prevent long IPC messages). 54 // via IPC (to prevent long IPC messages).
55 const size_t kMaximumDataListSizeForAutofill = 30; 55 const size_t kMaximumDataListSizeForAutofill = 30;
56 56
57 // A query counter for requests to show an interactive autocomplete UI.
58 int request_autocomplete_query_id_ = 0;
59
57 void AppendDataListSuggestions(const WebKit::WebInputElement& element, 60 void AppendDataListSuggestions(const WebKit::WebInputElement& element,
58 std::vector<string16>* values, 61 std::vector<string16>* values,
59 std::vector<string16>* labels, 62 std::vector<string16>* labels,
60 std::vector<string16>* icons, 63 std::vector<string16>* icons,
61 std::vector<int>* item_ids) { 64 std::vector<int>* item_ids) {
62 WebNodeCollection options = element.dataListOptions(); 65 WebNodeCollection options = element.dataListOptions();
63 if (options.isNull()) 66 if (options.isNull())
64 return; 67 return;
65 68
66 string16 prefix = element.editingValue(); 69 string16 prefix = element.editingValue();
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview, 155 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview,
153 OnSetAutofillActionPreview) 156 OnSetAutofillActionPreview)
154 IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm, 157 IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm,
155 OnClearPreviewedForm) 158 OnClearPreviewedForm)
156 IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText, 159 IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText,
157 OnSetNodeText) 160 OnSetNodeText)
158 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion, 161 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion,
159 OnAcceptDataListSuggestion) 162 OnAcceptDataListSuggestion)
160 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion, 163 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion,
161 OnAcceptPasswordAutofillSuggestion) 164 OnAcceptPasswordAutofillSuggestion)
165 IPC_MESSAGE_HANDLER(AutofillMsg_RequestAutocompleteFinished,
166 OnRequestAutocompleteFinished)
162 IPC_MESSAGE_UNHANDLED(handled = false) 167 IPC_MESSAGE_UNHANDLED(handled = false)
163 IPC_END_MESSAGE_MAP() 168 IPC_END_MESSAGE_MAP()
164 return handled; 169 return handled;
165 } 170 }
166 171
167 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) { 172 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) {
168 // The document has now been fully loaded. Scan for forms to be sent up to 173 // The document has now been fully loaded. Scan for forms to be sent up to
169 // the browser. 174 // the browser.
170 std::vector<FormData> forms; 175 std::vector<FormData> forms;
171 form_cache_.ExtractForms(*frame, &forms); 176 form_cache_.ExtractForms(*frame, &forms);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 Send(new AutofillHostMsg_HideAutofillPopup(routing_id())); 211 Send(new AutofillHostMsg_HideAutofillPopup(routing_id()));
207 } 212 }
208 213
209 void AutofillAgent::DidChangeScrollOffset(WebKit::WebFrame*) { 214 void AutofillAgent::DidChangeScrollOffset(WebKit::WebFrame*) {
210 // Any time the scroll offset changes, the page's content moves, so Autofill 215 // Any time the scroll offset changes, the page's content moves, so Autofill
211 // popups should be hidden. This is only needed for the new Autofill UI 216 // popups should be hidden. This is only needed for the new Autofill UI
212 // because WebKit already knows to hide the old UI when this occurs. 217 // because WebKit already knows to hide the old UI when this occurs.
213 Send(new AutofillHostMsg_HideAutofillPopup(routing_id())); 218 Send(new AutofillHostMsg_HideAutofillPopup(routing_id()));
214 } 219 }
215 220
221 void AutofillAgent::RequestAutocomplete(WebKit::WebFrame* frame,
222 const WebFormElement& form) {
223 request_autocomplete_query_id_ += 1;
224
225 // Cancel any pending autofill requests.
226 autofill_query_id_ += 1;
227
228 // Any popup currently showing is obsolete.
229 HidePopups();
230
231 FormData form_data;
232 if (WebFormElementToFormData(form,
233 WebFormControlElement(),
234 REQUIRE_AUTOCOMPLETE,
235 EXTRACT_NONE,
236 &form_data,
237 NULL)) {
238 form_ = form;
239 Send(new AutofillHostMsg_RequestAutocomplete(
240 routing_id(), request_autocomplete_query_id_, form_data));
241 }
242 }
243
216 bool AutofillAgent::InputElementClicked(const WebInputElement& element, 244 bool AutofillAgent::InputElementClicked(const WebInputElement& element,
217 bool was_focused, 245 bool was_focused,
218 bool is_focused) { 246 bool is_focused) {
219 if (was_focused) 247 if (was_focused)
220 ShowSuggestions(element, true, false, true); 248 ShowSuggestions(element, true, false, true);
221 249
222 return false; 250 return false;
223 } 251 }
224 252
225 bool AutofillAgent::InputElementLostFocus() { 253 bool AutofillAgent::InputElementLostFocus() {
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 void AutofillAgent::OnAcceptPasswordAutofillSuggestion(const string16& value) { 603 void AutofillAgent::OnAcceptPasswordAutofillSuggestion(const string16& value) {
576 // We need to make sure this is handled here because the browser process 604 // We need to make sure this is handled here because the browser process
577 // skipped it handling because it believed it would be handled here. If it 605 // skipped it handling because it believed it would be handled here. If it
578 // isn't handled here then the browser logic needs to be updated. 606 // isn't handled here then the browser logic needs to be updated.
579 bool handled = password_autofill_manager_->DidAcceptAutofillSuggestion( 607 bool handled = password_autofill_manager_->DidAcceptAutofillSuggestion(
580 element_, 608 element_,
581 value); 609 value);
582 DCHECK(handled); 610 DCHECK(handled);
583 } 611 }
584 612
613 void AutofillAgent::OnRequestAutocompleteFinished(int query_id, bool success) {
614 DCHECK_GT(query_id, 0);
615 if (query_id == request_autocomplete_query_id_)
616 form_.dispatchAutocompleteEvent(success);
617 }
618
585 void AutofillAgent::ShowSuggestions(const WebInputElement& element, 619 void AutofillAgent::ShowSuggestions(const WebInputElement& element,
586 bool autofill_on_empty_values, 620 bool autofill_on_empty_values,
587 bool requires_caret_at_end, 621 bool requires_caret_at_end,
588 bool display_warning_if_disabled) { 622 bool display_warning_if_disabled) {
589 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() || 623 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() ||
590 element.isPasswordField() || !element.suggestedValue().isEmpty()) 624 element.isPasswordField() || !element.suggestedValue().isEmpty())
591 return; 625 return;
592 626
593 // Don't attempt to autofill with values that are too large or if filling 627 // Don't attempt to autofill with values that are too large or if filling
594 // criteria are not met. 628 // criteria are not met.
595 WebString value = element.editingValue(); 629 WebString value = element.editingValue();
596 if (value.length() > kMaximumTextSizeForAutofill || 630 if (value.length() > kMaximumTextSizeForAutofill ||
597 (!autofill_on_empty_values && value.isEmpty()) || 631 (!autofill_on_empty_values && value.isEmpty()) ||
598 (requires_caret_at_end && 632 (requires_caret_at_end &&
599 (element.selectionStart() != element.selectionEnd() || 633 (element.selectionStart() != element.selectionEnd() ||
600 element.selectionEnd() != static_cast<int>(value.length())))) { 634 element.selectionEnd() != static_cast<int>(value.length())))) {
601 // Any popup currently showing is obsolete. 635 // Any popup currently showing is obsolete.
602 WebKit::WebView* web_view = render_view()->GetWebView(); 636 HidePopups();
603 if (web_view)
604 web_view->hidePopups();
605
606 return; 637 return;
607 } 638 }
608 639
609 element_ = element; 640 element_ = element;
610 641
611 // If autocomplete is disabled at the form level, then we might want to show 642 // If autocomplete is disabled at the form level, then we might want to show
612 // a warning in place of suggestions. However, if autocomplete is disabled 643 // a warning in place of suggestions. However, if autocomplete is disabled
613 // specifically for this field, we never want to show a warning. Otherwise, 644 // specifically for this field, we never want to show a warning. Otherwise,
614 // we might interfere with custom popups (e.g. search suggestions) used by 645 // we might interfere with custom popups (e.g. search suggestions) used by
615 // the website. Also, if the field has no name, then we won't have values. 646 // the website. Also, if the field has no name, then we won't have values.
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 726
696 void AutofillAgent::SetNodeText(const string16& value, 727 void AutofillAgent::SetNodeText(const string16& value,
697 WebKit::WebInputElement* node) { 728 WebKit::WebInputElement* node) {
698 did_set_node_text_ = true; 729 did_set_node_text_ = true;
699 string16 substring = value; 730 string16 substring = value;
700 substring = substring.substr(0, node->maxLength()); 731 substring = substring.substr(0, node->maxLength());
701 732
702 node->setEditingValue(substring); 733 node->setEditingValue(substring);
703 } 734 }
704 735
736 void AutofillAgent::HidePopups() {
737 WebKit::WebView* web_view = render_view()->GetWebView();
738 if (web_view)
739 web_view->hidePopups();
740 }
741
742
705 } // namespace autofill 743 } // namespace autofill
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698