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

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: remove forward 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
« no previous file with comments | « chrome/renderer/autofill/autofill_agent.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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"
11 #include "base/time.h" 11 #include "base/time.h"
12 #include "base/utf_string_conversions.h" 12 #include "base/utf_string_conversions.h"
13 #include "chrome/common/autofill_messages.h" 13 #include "chrome/common/autofill_messages.h"
14 #include "chrome/common/chrome_constants.h" 14 #include "chrome/common/chrome_constants.h"
15 #include "chrome/common/form_data.h" 15 #include "chrome/common/form_data.h"
16 #include "chrome/common/form_data_predictions.h" 16 #include "chrome/common/form_data_predictions.h"
17 #include "chrome/common/form_field_data.h" 17 #include "chrome/common/form_field_data.h"
18 #include "chrome/renderer/autofill/form_autofill_util.h" 18 #include "chrome/renderer/autofill/form_autofill_util.h"
19 #include "chrome/renderer/autofill/password_autofill_manager.h" 19 #include "chrome/renderer/autofill/password_autofill_manager.h"
20 #include "content/public/common/password_form.h" 20 #include "content/public/common/password_form.h"
21 #include "content/public/renderer/render_view.h" 21 #include "content/public/renderer/render_view.h"
22 #include "grit/chromium_strings.h" 22 #include "grit/chromium_strings.h"
23 #include "grit/generated_resources.h" 23 #include "grit/generated_resources.h"
24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h" 24 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebRect.h"
25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement .h" 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormControlElement .h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFormElement.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h" 29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h" 30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNode.h"
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeCollection.h" 31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebNodeCollection.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebOptionElement.h" 32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebOptionElement.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
33 #include "ui/base/keycodes/keyboard_codes.h" 34 #include "ui/base/keycodes/keyboard_codes.h"
34 #include "ui/base/l10n/l10n_util.h" 35 #include "ui/base/l10n/l10n_util.h"
35 36
36 using WebKit::WebAutofillClient; 37 using WebKit::WebAutofillClient;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 content::RenderView* render_view, 124 content::RenderView* render_view,
124 PasswordAutofillManager* password_autofill_manager) 125 PasswordAutofillManager* password_autofill_manager)
125 : content::RenderViewObserver(render_view), 126 : content::RenderViewObserver(render_view),
126 password_autofill_manager_(password_autofill_manager), 127 password_autofill_manager_(password_autofill_manager),
127 autofill_query_id_(0), 128 autofill_query_id_(0),
128 autofill_action_(AUTOFILL_NONE), 129 autofill_action_(AUTOFILL_NONE),
129 display_warning_if_disabled_(false), 130 display_warning_if_disabled_(false),
130 was_query_node_autofilled_(false), 131 was_query_node_autofilled_(false),
131 has_shown_autofill_popup_for_current_edit_(false), 132 has_shown_autofill_popup_for_current_edit_(false),
132 did_set_node_text_(false), 133 did_set_node_text_(false),
134 has_requested_autocomplete_(false),
133 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) { 135 ALLOW_THIS_IN_INITIALIZER_LIST(weak_ptr_factory_(this)) {
134 render_view->GetWebView()->setAutofillClient(this); 136 render_view->GetWebView()->setAutofillClient(this);
135 } 137 }
136 138
137 AutofillAgent::~AutofillAgent() {} 139 AutofillAgent::~AutofillAgent() {}
138 140
139 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) { 141 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) {
140 bool handled = true; 142 bool handled = true;
141 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message) 143 IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message)
142 IPC_MESSAGE_HANDLER(AutofillMsg_SuggestionsReturned, OnSuggestionsReturned) 144 IPC_MESSAGE_HANDLER(AutofillMsg_SuggestionsReturned, OnSuggestionsReturned)
143 IPC_MESSAGE_HANDLER(AutofillMsg_FormDataFilled, OnFormDataFilled) 145 IPC_MESSAGE_HANDLER(AutofillMsg_FormDataFilled, OnFormDataFilled)
144 IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable, 146 IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable,
145 OnFieldTypePredictionsAvailable) 147 OnFieldTypePredictionsAvailable)
146 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionFill, 148 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionFill,
147 OnSetAutofillActionFill) 149 OnSetAutofillActionFill)
148 IPC_MESSAGE_HANDLER(AutofillMsg_ClearForm, 150 IPC_MESSAGE_HANDLER(AutofillMsg_ClearForm,
149 OnClearForm) 151 OnClearForm)
150 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview, 152 IPC_MESSAGE_HANDLER(AutofillMsg_SetAutofillActionPreview,
151 OnSetAutofillActionPreview) 153 OnSetAutofillActionPreview)
152 IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm, 154 IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm,
153 OnClearPreviewedForm) 155 OnClearPreviewedForm)
154 IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText, 156 IPC_MESSAGE_HANDLER(AutofillMsg_SetNodeText,
155 OnSetNodeText) 157 OnSetNodeText)
156 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion, 158 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion,
157 OnAcceptDataListSuggestion) 159 OnAcceptDataListSuggestion)
158 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion, 160 IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion,
159 OnAcceptPasswordAutofillSuggestion) 161 OnAcceptPasswordAutofillSuggestion)
162 IPC_MESSAGE_HANDLER(AutofillMsg_RequestAutocompleteFinished,
163 OnRequestAutocompleteFinished)
160 IPC_MESSAGE_UNHANDLED(handled = false) 164 IPC_MESSAGE_UNHANDLED(handled = false)
161 IPC_END_MESSAGE_MAP() 165 IPC_END_MESSAGE_MAP()
162 return handled; 166 return handled;
163 } 167 }
164 168
165 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) { 169 void AutofillAgent::DidFinishDocumentLoad(WebFrame* frame) {
166 // The document has now been fully loaded. Scan for forms to be sent up to 170 // The document has now been fully loaded. Scan for forms to be sent up to
167 // the browser. 171 // the browser.
168 std::vector<FormData> forms; 172 std::vector<FormData> forms;
169 form_cache_.ExtractForms(*frame, &forms); 173 form_cache_.ExtractForms(*frame, &forms);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 Send(new AutofillHostMsg_HideAutofillPopup(routing_id())); 208 Send(new AutofillHostMsg_HideAutofillPopup(routing_id()));
205 } 209 }
206 210
207 void AutofillAgent::DidChangeScrollOffset(WebKit::WebFrame*) { 211 void AutofillAgent::DidChangeScrollOffset(WebKit::WebFrame*) {
208 // Any time the scroll offset changes, the page's content moves, so Autofill 212 // Any time the scroll offset changes, the page's content moves, so Autofill
209 // popups should be hidden. This is only needed for the new Autofill UI 213 // popups should be hidden. This is only needed for the new Autofill UI
210 // because WebKit already knows to hide the old UI when this occurs. 214 // because WebKit already knows to hide the old UI when this occurs.
211 Send(new AutofillHostMsg_HideAutofillPopup(routing_id())); 215 Send(new AutofillHostMsg_HideAutofillPopup(routing_id()));
212 } 216 }
213 217
218 void AutofillAgent::didRequestAutocomplete(WebKit::WebFrame* frame,
219 const WebFormElement& form) {
220 if (has_requested_autocomplete_)
221 return;
222
223 // Cancel any pending autofill requests.
Ilya Sherman 2012/10/29 21:27:47 nit: "autofill" -> "Autofill"
Dan Beam 2012/10/29 23:08:24 D'oh, sorry, done.
224 ++autofill_query_id_;
225
226 // Any popup currently showing is obsolete.
227 HidePopups();
228
229 FormData form_data;
230 if (WebFormElementToFormData(form,
231 WebFormControlElement(),
232 REQUIRE_AUTOCOMPLETE,
233 EXTRACT_NONE,
234 &form_data,
235 NULL)) {
236 form_ = form;
237 has_requested_autocomplete_ = true;
238 Send(new AutofillHostMsg_RequestAutocomplete(routing_id(), form_data));
239 }
240 }
241
214 bool AutofillAgent::InputElementClicked(const WebInputElement& element, 242 bool AutofillAgent::InputElementClicked(const WebInputElement& element,
215 bool was_focused, 243 bool was_focused,
216 bool is_focused) { 244 bool is_focused) {
217 if (was_focused) 245 if (was_focused)
218 ShowSuggestions(element, true, false, true); 246 ShowSuggestions(element, true, false, true);
219 247
220 return false; 248 return false;
221 } 249 }
222 250
223 bool AutofillAgent::InputElementLostFocus() { 251 bool AutofillAgent::InputElementLostFocus() {
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
567 void AutofillAgent::OnAcceptPasswordAutofillSuggestion(const string16& value) { 595 void AutofillAgent::OnAcceptPasswordAutofillSuggestion(const string16& value) {
568 // We need to make sure this is handled here because the browser process 596 // We need to make sure this is handled here because the browser process
569 // skipped it handling because it believed it would be handled here. If it 597 // skipped it handling because it believed it would be handled here. If it
570 // isn't handled here then the browser logic needs to be updated. 598 // isn't handled here then the browser logic needs to be updated.
571 bool handled = password_autofill_manager_->DidAcceptAutofillSuggestion( 599 bool handled = password_autofill_manager_->DidAcceptAutofillSuggestion(
572 element_, 600 element_,
573 value); 601 value);
574 DCHECK(handled); 602 DCHECK(handled);
575 } 603 }
576 604
605 void AutofillAgent::OnRequestAutocompleteFinished(int result) {
606 if (!has_requested_autocomplete_)
607 return;
Ilya Sherman 2012/10/29 21:27:47 nit: Can this be a DCHECK instead?
Dan Beam 2012/10/29 23:08:24 Done.
608
609 has_requested_autocomplete_ = false;
610
611 if (result == WebFormElement::AutocompleteSuccess ||
612 result == WebFormElement::AutocompleteError) {
613 form_.finishRequestAutocomplete(
614 static_cast<WebFormElement::AutocompleteResult>(result));
615 } else {
616 NOTREACHED();
617 }
Ilya Sherman 2012/10/29 21:27:47 Optional nit: Maybe write this as a DCHECK() + rem
Dan Beam 2012/10/29 23:08:24 Done.
618 }
619
577 void AutofillAgent::ShowSuggestions(const WebInputElement& element, 620 void AutofillAgent::ShowSuggestions(const WebInputElement& element,
578 bool autofill_on_empty_values, 621 bool autofill_on_empty_values,
579 bool requires_caret_at_end, 622 bool requires_caret_at_end,
580 bool display_warning_if_disabled) { 623 bool display_warning_if_disabled) {
581 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() || 624 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() ||
582 element.isPasswordField() || !element.suggestedValue().isEmpty()) 625 element.isPasswordField() || !element.suggestedValue().isEmpty())
583 return; 626 return;
584 627
585 // Don't attempt to autofill with values that are too large or if filling 628 // Don't attempt to autofill with values that are too large or if filling
586 // criteria are not met. 629 // criteria are not met.
587 WebString value = element.editingValue(); 630 WebString value = element.editingValue();
588 if (value.length() > kMaximumTextSizeForAutofill || 631 if (value.length() > kMaximumTextSizeForAutofill ||
589 (!autofill_on_empty_values && value.isEmpty()) || 632 (!autofill_on_empty_values && value.isEmpty()) ||
590 (requires_caret_at_end && 633 (requires_caret_at_end &&
591 (element.selectionStart() != element.selectionEnd() || 634 (element.selectionStart() != element.selectionEnd() ||
592 element.selectionEnd() != static_cast<int>(value.length())))) { 635 element.selectionEnd() != static_cast<int>(value.length())))) {
593 // Any popup currently showing is obsolete. 636 // Any popup currently showing is obsolete.
594 WebKit::WebView* web_view = render_view()->GetWebView(); 637 HidePopups();
595 if (web_view)
596 web_view->hidePopups();
597
598 return; 638 return;
599 } 639 }
600 640
601 element_ = element; 641 element_ = element;
602 642
603 // If autocomplete is disabled at the form level, then we might want to show 643 // If autocomplete is disabled at the form level, then we might want to show
604 // a warning in place of suggestions. However, if autocomplete is disabled 644 // a warning in place of suggestions. However, if autocomplete is disabled
605 // specifically for this field, we never want to show a warning. Otherwise, 645 // specifically for this field, we never want to show a warning. Otherwise,
606 // we might interfere with custom popups (e.g. search suggestions) used by 646 // we might interfere with custom popups (e.g. search suggestions) used by
607 // the website. Also, if the field has no name, then we won't have values. 647 // 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
687 727
688 void AutofillAgent::SetNodeText(const string16& value, 728 void AutofillAgent::SetNodeText(const string16& value,
689 WebKit::WebInputElement* node) { 729 WebKit::WebInputElement* node) {
690 did_set_node_text_ = true; 730 did_set_node_text_ = true;
691 string16 substring = value; 731 string16 substring = value;
692 substring = substring.substr(0, node->maxLength()); 732 substring = substring.substr(0, node->maxLength());
693 733
694 node->setEditingValue(substring); 734 node->setEditingValue(substring);
695 } 735 }
696 736
737 void AutofillAgent::HidePopups() {
738 WebKit::WebView* web_view = render_view()->GetWebView();
739 if (web_view)
740 web_view->hidePopups();
741 }
742
697 } // namespace autofill 743 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/renderer/autofill/autofill_agent.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698