Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / autofill / content / renderer / autofill_agent.cc
1 // Copyright 2013 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/content/renderer/autofill_agent.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/strings/string_split.h"
11 #include "base/strings/string_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h"
14 #include "components/autofill/content/common/autofill_messages.h"
15 #include "components/autofill/content/renderer/form_autofill_util.h"
16 #include "components/autofill/content/renderer/page_click_tracker.h"
17 #include "components/autofill/content/renderer/password_autofill_agent.h"
18 #include "components/autofill/content/renderer/password_generation_agent.h"
19 #include "components/autofill/core/common/autofill_constants.h"
20 #include "components/autofill/core/common/autofill_data_validation.h"
21 #include "components/autofill/core/common/autofill_switches.h"
22 #include "components/autofill/core/common/form_data.h"
23 #include "components/autofill/core/common/form_data_predictions.h"
24 #include "components/autofill/core/common/form_field_data.h"
25 #include "components/autofill/core/common/password_form.h"
26 #include "components/autofill/core/common/web_element_descriptor.h"
27 #include "content/public/common/content_switches.h"
28 #include "content/public/common/ssl_status.h"
29 #include "content/public/common/url_constants.h"
30 #include "content/public/renderer/render_view.h"
31 #include "grit/component_strings.h"
32 #include "net/cert/cert_status_flags.h"
33 #include "third_party/WebKit/public/platform/WebRect.h"
34 #include "third_party/WebKit/public/platform/WebURLRequest.h"
35 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
36 #include "third_party/WebKit/public/web/WebDataSource.h"
37 #include "third_party/WebKit/public/web/WebDocument.h"
38 #include "third_party/WebKit/public/web/WebElementCollection.h"
39 #include "third_party/WebKit/public/web/WebFormControlElement.h"
40 #include "third_party/WebKit/public/web/WebFormElement.h"
41 #include "third_party/WebKit/public/web/WebInputEvent.h"
42 #include "third_party/WebKit/public/web/WebLocalFrame.h"
43 #include "third_party/WebKit/public/web/WebNode.h"
44 #include "third_party/WebKit/public/web/WebOptionElement.h"
45 #include "third_party/WebKit/public/web/WebTextAreaElement.h"
46 #include "third_party/WebKit/public/web/WebView.h"
47 #include "ui/base/l10n/l10n_util.h"
48 #include "ui/events/keycodes/keyboard_codes.h"
49
50 using blink::WebAutofillClient;
51 using blink::WebConsoleMessage;
52 using blink::WebElement;
53 using blink::WebElementCollection;
54 using blink::WebFormControlElement;
55 using blink::WebFormElement;
56 using blink::WebFrame;
57 using blink::WebInputElement;
58 using blink::WebKeyboardEvent;
59 using blink::WebLocalFrame;
60 using blink::WebNode;
61 using blink::WebOptionElement;
62 using blink::WebString;
63 using blink::WebTextAreaElement;
64 using blink::WebVector;
65
66 namespace autofill {
67
68 namespace {
69
70 // Gets all the data list values (with corresponding label) for the given
71 // element.
72 void GetDataListSuggestions(const WebInputElement& element,
73                             bool ignore_current_value,
74                             std::vector<base::string16>* values,
75                             std::vector<base::string16>* labels) {
76   WebElementCollection options = element.dataListOptions();
77   if (options.isNull())
78     return;
79
80   base::string16 prefix;
81   if (!ignore_current_value) {
82     prefix = element.editingValue();
83     if (element.isMultiple() &&
84         element.formControlType() == WebString::fromUTF8("email")) {
85       std::vector<base::string16> parts;
86       base::SplitStringDontTrim(prefix, ',', &parts);
87       if (parts.size() > 0) {
88         base::TrimWhitespace(parts[parts.size() - 1], base::TRIM_LEADING,
89                              &prefix);
90       }
91     }
92   }
93   for (WebOptionElement option = options.firstItem().to<WebOptionElement>();
94        !option.isNull(); option = options.nextItem().to<WebOptionElement>()) {
95     if (!StartsWith(option.value(), prefix, false) ||
96         option.value() == prefix ||
97         !element.isValidValue(option.value()))
98       continue;
99
100     values->push_back(option.value());
101     if (option.value() != option.label())
102       labels->push_back(option.label());
103     else
104       labels->push_back(base::string16());
105   }
106 }
107
108 // Trim the vector before sending it to the browser process to ensure we
109 // don't send too much data through the IPC.
110 void TrimStringVectorForIPC(std::vector<base::string16>* strings) {
111   // Limit the size of the vector.
112   if (strings->size() > kMaxListSize)
113     strings->resize(kMaxListSize);
114
115   // Limit the size of the strings in the vector.
116   for (size_t i = 0; i < strings->size(); ++i) {
117     if ((*strings)[i].length() > kMaxDataLength)
118       (*strings)[i].resize(kMaxDataLength);
119   }
120 }
121
122 }  // namespace
123
124 AutofillAgent::AutofillAgent(content::RenderView* render_view,
125                              PasswordAutofillAgent* password_autofill_agent,
126                              PasswordGenerationAgent* password_generation_agent)
127     : content::RenderViewObserver(render_view),
128       password_autofill_agent_(password_autofill_agent),
129       password_generation_agent_(password_generation_agent),
130       autofill_query_id_(0),
131       web_view_(render_view->GetWebView()),
132       display_warning_if_disabled_(false),
133       was_query_node_autofilled_(false),
134       has_shown_autofill_popup_for_current_edit_(false),
135       did_set_node_text_(false),
136       has_new_forms_for_browser_(false),
137       ignore_text_changes_(false),
138       is_popup_possibly_visible_(false),
139       weak_ptr_factory_(this) {
140   render_view->GetWebView()->setAutofillClient(this);
141
142   // The PageClickTracker is a RenderViewObserver, and hence will be freed when
143   // the RenderView is destroyed.
144   new PageClickTracker(render_view, this);
145 }
146
147 AutofillAgent::~AutofillAgent() {}
148
149 bool AutofillAgent::OnMessageReceived(const IPC::Message& message) {
150   bool handled = true;
151   IPC_BEGIN_MESSAGE_MAP(AutofillAgent, message)
152     IPC_MESSAGE_HANDLER(AutofillMsg_FillForm, OnFillForm)
153     IPC_MESSAGE_HANDLER(AutofillMsg_PreviewForm, OnPreviewForm)
154     IPC_MESSAGE_HANDLER(AutofillMsg_FieldTypePredictionsAvailable,
155                         OnFieldTypePredictionsAvailable)
156     IPC_MESSAGE_HANDLER(AutofillMsg_ClearForm, OnClearForm)
157     IPC_MESSAGE_HANDLER(AutofillMsg_ClearPreviewedForm, OnClearPreviewedForm)
158     IPC_MESSAGE_HANDLER(AutofillMsg_FillFieldWithValue, OnFillFieldWithValue)
159     IPC_MESSAGE_HANDLER(AutofillMsg_PreviewFieldWithValue,
160                         OnPreviewFieldWithValue)
161     IPC_MESSAGE_HANDLER(AutofillMsg_AcceptDataListSuggestion,
162                         OnAcceptDataListSuggestion)
163     IPC_MESSAGE_HANDLER(AutofillMsg_AcceptPasswordAutofillSuggestion,
164                         OnAcceptPasswordAutofillSuggestion)
165     IPC_MESSAGE_HANDLER(AutofillMsg_RequestAutocompleteResult,
166                         OnRequestAutocompleteResult)
167     IPC_MESSAGE_UNHANDLED(handled = false)
168   IPC_END_MESSAGE_MAP()
169   return handled;
170 }
171
172 void AutofillAgent::DidFinishDocumentLoad(WebLocalFrame* frame) {
173   // Record timestamp on document load. This is used to record overhead of
174   // Autofill feature.
175   forms_seen_timestamp_ = base::TimeTicks::Now();
176
177   // The document has now been fully loaded.  Scan for forms to be sent up to
178   // the browser.
179   std::vector<FormData> forms;
180   bool has_more_forms = false;
181   if (!frame->parent()) {
182     form_elements_.clear();
183     has_more_forms = form_cache_.ExtractFormsAndFormElements(
184         *frame, kRequiredAutofillFields, &forms, &form_elements_);
185   } else {
186     form_cache_.ExtractForms(*frame, &forms);
187   }
188
189   autofill::FormsSeenState state = has_more_forms ?
190       autofill::PARTIAL_FORMS_SEEN : autofill::NO_SPECIAL_FORMS_SEEN;
191
192   // Always communicate to browser process for topmost frame.
193   if (!forms.empty() || !frame->parent()) {
194     Send(new AutofillHostMsg_FormsSeen(routing_id(), forms,
195                                        forms_seen_timestamp_,
196                                        state));
197   }
198 }
199
200 void AutofillAgent::FrameDetached(WebFrame* frame) {
201   form_cache_.ResetFrame(*frame);
202 }
203
204 void AutofillAgent::FrameWillClose(WebFrame* frame) {
205   if (in_flight_request_form_.isNull())
206     return;
207
208   for (WebFrame* temp = in_flight_request_form_.document().frame();
209        temp; temp = temp->parent()) {
210     if (temp == frame) {
211       Send(new AutofillHostMsg_CancelRequestAutocomplete(routing_id()));
212       break;
213     }
214   }
215 }
216
217 void AutofillAgent::WillSubmitForm(WebLocalFrame* frame,
218                                    const WebFormElement& form) {
219   FormData form_data;
220   if (WebFormElementToFormData(form,
221                                WebFormControlElement(),
222                                REQUIRE_AUTOCOMPLETE,
223                                static_cast<ExtractMask>(
224                                    EXTRACT_VALUE | EXTRACT_OPTION_TEXT),
225                                &form_data,
226                                NULL)) {
227     Send(new AutofillHostMsg_FormSubmitted(routing_id(), form_data,
228                                            base::TimeTicks::Now()));
229   }
230 }
231
232 void AutofillAgent::ZoomLevelChanged() {
233   // Any time the zoom level changes, the page's content moves, so any Autofill
234   // popups should be hidden. This is only needed for the new Autofill UI
235   // because WebKit already knows to hide the old UI when this occurs.
236   HidePopup();
237 }
238
239 void AutofillAgent::FocusedNodeChanged(const WebNode& node) {
240   if (password_generation_agent_ &&
241       password_generation_agent_->FocusedNodeHasChanged(node)) {
242     is_popup_possibly_visible_ = true;
243     return;
244   }
245
246   if (node.isNull() || !node.isElementNode())
247     return;
248
249   WebElement web_element = node.toConst<WebElement>();
250
251   if (!web_element.document().frame())
252       return;
253
254   const WebInputElement* element = toWebInputElement(&web_element);
255
256   if (!element || !element->isEnabled() || element->isReadOnly() ||
257       !element->isTextField() || element->isPasswordField())
258     return;
259
260   element_ = *element;
261 }
262
263 void AutofillAgent::OrientationChangeEvent() {
264   HidePopup();
265 }
266
267 void AutofillAgent::DidChangeScrollOffset(WebLocalFrame*) {
268   HidePopup();
269 }
270
271 void AutofillAgent::didRequestAutocomplete(
272     const WebFormElement& form,
273     const blink::WebAutocompleteParams& details) {
274   // TODO(estade): honor |details|.
275
276   // Disallow the dialog over non-https or broken https, except when the
277   // ignore SSL flag is passed. See http://crbug.com/272512.
278   // TODO(palmer): this should be moved to the browser process after frames
279   // get their own processes.
280   GURL url(form.document().url());
281   content::SSLStatus ssl_status =
282       render_view()->GetSSLStatusOfFrame(form.document().frame());
283   bool is_safe = url.SchemeIs(url::kHttpsScheme) &&
284       !net::IsCertStatusError(ssl_status.cert_status);
285   bool allow_unsafe = CommandLine::ForCurrentProcess()->HasSwitch(
286       ::switches::kReduceSecurityForTesting);
287
288   FormData form_data;
289   std::string error_message;
290   if (!in_flight_request_form_.isNull()) {
291     error_message = "already active.";
292   } else if (!is_safe && !allow_unsafe) {
293     error_message =
294         "must use a secure connection or --reduce-security-for-testing.";
295   } else if (!WebFormElementToFormData(form,
296                                        WebFormControlElement(),
297                                        REQUIRE_AUTOCOMPLETE,
298                                        EXTRACT_OPTIONS,
299                                        &form_data,
300                                        NULL)) {
301     error_message = "failed to parse form.";
302   }
303
304   if (!error_message.empty()) {
305     WebConsoleMessage console_message = WebConsoleMessage(
306         WebConsoleMessage::LevelLog,
307         WebString(base::ASCIIToUTF16("requestAutocomplete: ") +
308                       base::ASCIIToUTF16(error_message)));
309     WebFormElement(form).finishRequestAutocomplete(
310         WebFormElement::AutocompleteResultErrorDisabled);
311     return;
312   }
313
314   // Cancel any pending Autofill requests and hide any currently showing popups.
315   ++autofill_query_id_;
316   HidePopup();
317
318   in_flight_request_form_ = form;
319   Send(new AutofillHostMsg_RequestAutocomplete(routing_id(), form_data, url));
320 }
321
322 void AutofillAgent::setIgnoreTextChanges(bool ignore) {
323   ignore_text_changes_ = ignore;
324 }
325
326 void AutofillAgent::FormControlElementClicked(
327     const WebFormControlElement& element,
328     bool was_focused) {
329   const WebInputElement* input_element = toWebInputElement(&element);
330   if (!input_element && !IsTextAreaElement(element))
331     return;
332
333   if (was_focused)
334     ShowSuggestions(element, true, false, true, false);
335 }
336
337 void AutofillAgent::FormControlElementLostFocus() {
338   HidePopup();
339 }
340
341 void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) {
342   password_autofill_agent_->TextFieldDidEndEditing(element);
343   has_shown_autofill_popup_for_current_edit_ = false;
344   Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id()));
345 }
346
347 void AutofillAgent::textFieldDidChange(const WebFormControlElement& element) {
348   if (ignore_text_changes_)
349     return;
350
351   DCHECK(toWebInputElement(&element) || IsTextAreaElement(element));
352
353   if (did_set_node_text_) {
354     did_set_node_text_ = false;
355     return;
356   }
357
358   // We post a task for doing the Autofill as the caret position is not set
359   // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and
360   // it is needed to trigger autofill.
361   weak_ptr_factory_.InvalidateWeakPtrs();
362   base::MessageLoop::current()->PostTask(
363       FROM_HERE,
364       base::Bind(&AutofillAgent::TextFieldDidChangeImpl,
365                  weak_ptr_factory_.GetWeakPtr(),
366                  element));
367 }
368
369 void AutofillAgent::TextFieldDidChangeImpl(
370     const WebFormControlElement& element) {
371   // If the element isn't focused then the changes don't matter. This check is
372   // required to properly handle IME interactions.
373   if (!element.focused())
374     return;
375
376   const WebInputElement* input_element = toWebInputElement(&element);
377   if (input_element) {
378     if (password_generation_agent_ &&
379         password_generation_agent_->TextDidChangeInTextField(*input_element)) {
380       is_popup_possibly_visible_ = true;
381       return;
382     }
383
384     if (password_autofill_agent_->TextDidChangeInTextField(*input_element)) {
385       element_ = element;
386       return;
387     }
388   }
389
390   ShowSuggestions(element, false, true, false, false);
391
392   FormData form;
393   FormFieldData field;
394   if (FindFormAndFieldForFormControlElement(element,
395                                             &form,
396                                             &field,
397                                             REQUIRE_NONE)) {
398     Send(new AutofillHostMsg_TextFieldDidChange(routing_id(), form, field,
399                                                 base::TimeTicks::Now()));
400   }
401 }
402
403 void AutofillAgent::textFieldDidReceiveKeyDown(const WebInputElement& element,
404                                                const WebKeyboardEvent& event) {
405   if (password_autofill_agent_->TextFieldHandlingKeyDown(element, event)) {
406     element_ = element;
407     return;
408   }
409
410   if (event.windowsKeyCode == ui::VKEY_DOWN ||
411       event.windowsKeyCode == ui::VKEY_UP)
412     ShowSuggestions(element, true, true, true, false);
413 }
414
415 void AutofillAgent::openTextDataListChooser(const WebInputElement& element) {
416     ShowSuggestions(element, true, false, false, true);
417 }
418
419 void AutofillAgent::firstUserGestureObserved() {
420   password_autofill_agent_->FirstUserGestureObserved();
421 }
422
423 void AutofillAgent::AcceptDataListSuggestion(
424     const base::string16& suggested_value) {
425   WebInputElement* input_element = toWebInputElement(&element_);
426   DCHECK(input_element);
427   base::string16 new_value = suggested_value;
428   // If this element takes multiple values then replace the last part with
429   // the suggestion.
430   if (input_element->isMultiple() &&
431       input_element->formControlType() == WebString::fromUTF8("email")) {
432     std::vector<base::string16> parts;
433
434     base::SplitStringDontTrim(input_element->editingValue(), ',', &parts);
435     if (parts.size() == 0)
436       parts.push_back(base::string16());
437
438     base::string16 last_part = parts.back();
439     // We want to keep just the leading whitespace.
440     for (size_t i = 0; i < last_part.size(); ++i) {
441       if (!IsWhitespace(last_part[i])) {
442         last_part = last_part.substr(0, i);
443         break;
444       }
445     }
446     last_part.append(suggested_value);
447     parts[parts.size() - 1] = last_part;
448
449     new_value = JoinString(parts, ',');
450   }
451   FillFieldWithValue(new_value, input_element);
452 }
453
454 void AutofillAgent::OnFieldTypePredictionsAvailable(
455     const std::vector<FormDataPredictions>& forms) {
456   for (size_t i = 0; i < forms.size(); ++i) {
457     form_cache_.ShowPredictions(forms[i]);
458   }
459 }
460
461 void AutofillAgent::OnFillForm(int query_id, const FormData& form) {
462   if (!render_view()->GetWebView() || query_id != autofill_query_id_)
463     return;
464
465   was_query_node_autofilled_ = element_.isAutofilled();
466   FillForm(form, element_);
467   Send(new AutofillHostMsg_DidFillAutofillFormData(routing_id(),
468                                                    base::TimeTicks::Now()));
469 }
470
471 void AutofillAgent::OnPreviewForm(int query_id, const FormData& form) {
472   if (!render_view()->GetWebView() || query_id != autofill_query_id_)
473     return;
474
475   was_query_node_autofilled_ = element_.isAutofilled();
476   PreviewForm(form, element_);
477   Send(new AutofillHostMsg_DidPreviewAutofillFormData(routing_id()));
478 }
479
480 void AutofillAgent::OnClearForm() {
481   form_cache_.ClearFormWithElement(element_);
482 }
483
484 void AutofillAgent::OnClearPreviewedForm() {
485   if (!element_.isNull()) {
486     if (password_autofill_agent_->DidClearAutofillSelection(element_))
487       return;
488
489     ClearPreviewedFormWithElement(element_, was_query_node_autofilled_);
490   } else {
491     // TODO(isherman): There seem to be rare cases where this code *is*
492     // reachable: see [ http://crbug.com/96321#c6 ].  Ideally we would
493     // understand those cases and fix the code to avoid them.  However, so far I
494     // have been unable to reproduce such a case locally.  If you hit this
495     // NOTREACHED(), please file a bug against me.
496     NOTREACHED();
497   }
498 }
499
500 void AutofillAgent::OnFillFieldWithValue(const base::string16& value) {
501   WebInputElement* input_element = toWebInputElement(&element_);
502   if (input_element)
503     FillFieldWithValue(value, input_element);
504 }
505
506 void AutofillAgent::OnPreviewFieldWithValue(const base::string16& value) {
507   WebInputElement* input_element = toWebInputElement(&element_);
508   if (input_element)
509     PreviewFieldWithValue(value, input_element);
510 }
511
512 void AutofillAgent::OnAcceptDataListSuggestion(const base::string16& value) {
513   AcceptDataListSuggestion(value);
514 }
515
516 void AutofillAgent::OnAcceptPasswordAutofillSuggestion(
517     const base::string16& username,
518     const base::string16& password) {
519   bool handled = password_autofill_agent_->AcceptSuggestion(
520       element_,
521       username,
522       password);
523   DCHECK(handled);
524 }
525
526 void AutofillAgent::OnRequestAutocompleteResult(
527     WebFormElement::AutocompleteResult result,
528     const base::string16& message,
529     const FormData& form_data) {
530   if (in_flight_request_form_.isNull())
531     return;
532
533   if (result == WebFormElement::AutocompleteResultSuccess) {
534     FillFormIncludingNonFocusableElements(form_data, in_flight_request_form_);
535     if (!in_flight_request_form_.checkValidity())
536       result = WebFormElement::AutocompleteResultErrorInvalid;
537   }
538
539   in_flight_request_form_.finishRequestAutocomplete(result);
540
541   if (!message.empty()) {
542     const base::string16 prefix(base::ASCIIToUTF16("requestAutocomplete: "));
543     WebConsoleMessage console_message = WebConsoleMessage(
544         WebConsoleMessage::LevelLog, WebString(prefix + message));
545     in_flight_request_form_.document().frame()->addMessageToConsole(
546         console_message);
547   }
548
549   in_flight_request_form_.reset();
550 }
551
552 void AutofillAgent::ShowSuggestions(const WebFormControlElement& element,
553                                     bool autofill_on_empty_values,
554                                     bool requires_caret_at_end,
555                                     bool display_warning_if_disabled,
556                                     bool datalist_only) {
557   if (!element.isEnabled() || element.isReadOnly())
558     return;
559
560   const WebInputElement* input_element = toWebInputElement(&element);
561   if (input_element) {
562     if (!input_element->isTextField() || input_element->isPasswordField())
563       return;
564     if (!datalist_only && !input_element->suggestedValue().isEmpty())
565       return;
566   } else {
567     DCHECK(IsTextAreaElement(element));
568     if (!element.toConst<WebTextAreaElement>().suggestedValue().isEmpty())
569       return;
570   }
571
572   // Don't attempt to autofill with values that are too large or if filling
573   // criteria are not met.
574   WebString value = element.editingValue();
575   if (!datalist_only &&
576       (value.length() > kMaxDataLength ||
577        (!autofill_on_empty_values && value.isEmpty()) ||
578        (requires_caret_at_end &&
579         (element.selectionStart() != element.selectionEnd() ||
580          element.selectionEnd() != static_cast<int>(value.length()))))) {
581     // Any popup currently showing is obsolete.
582     HidePopup();
583     return;
584   }
585
586   element_ = element;
587   if (input_element &&
588       password_autofill_agent_->ShowSuggestions(*input_element)) {
589     is_popup_possibly_visible_ = true;
590     return;
591   }
592
593   // If autocomplete is disabled at the field level, ensure that the native
594   // UI won't try to show a warning, since that may conflict with a custom
595   // popup. Note that we cannot use the WebKit method element.autoComplete()
596   // as it does not allow us to distinguish the case where autocomplete is
597   // disabled for *both* the element and for the form.
598   const base::string16 autocomplete_attribute =
599       element.getAttribute("autocomplete");
600   if (LowerCaseEqualsASCII(autocomplete_attribute, "off"))
601     display_warning_if_disabled = false;
602
603   QueryAutofillSuggestions(element,
604                            display_warning_if_disabled,
605                            datalist_only);
606 }
607
608 void AutofillAgent::QueryAutofillSuggestions(
609     const WebFormControlElement& element,
610     bool display_warning_if_disabled,
611     bool datalist_only) {
612   if (!element.document().frame())
613     return;
614
615   DCHECK(toWebInputElement(&element) || IsTextAreaElement(element));
616
617   static int query_counter = 0;
618   autofill_query_id_ = query_counter++;
619   display_warning_if_disabled_ = display_warning_if_disabled;
620
621   // If autocomplete is disabled at the form level, we want to see if there
622   // would have been any suggestions were it enabled, so that we can show a
623   // warning.  Otherwise, we want to ignore fields that disable autocomplete, so
624   // that the suggestions list does not include suggestions for these form
625   // fields -- see comment 1 on http://crbug.com/69914
626   const RequirementsMask requirements =
627       element.autoComplete() ? REQUIRE_AUTOCOMPLETE : REQUIRE_NONE;
628
629   FormData form;
630   FormFieldData field;
631   if (!FindFormAndFieldForFormControlElement(element, &form, &field,
632                                              requirements)) {
633     // If we didn't find the cached form, at least let autocomplete have a shot
634     // at providing suggestions.
635     WebFormControlElementToFormField(element, EXTRACT_VALUE, &field);
636   }
637   if (datalist_only)
638     field.should_autocomplete = false;
639
640   gfx::RectF bounding_box_scaled =
641       GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_);
642
643   std::vector<base::string16> data_list_values;
644   std::vector<base::string16> data_list_labels;
645   const WebInputElement* input_element = toWebInputElement(&element);
646   if (input_element) {
647     // Find the datalist values and send them to the browser process.
648     GetDataListSuggestions(*input_element,
649                            datalist_only,
650                            &data_list_values,
651                            &data_list_labels);
652     TrimStringVectorForIPC(&data_list_values);
653     TrimStringVectorForIPC(&data_list_labels);
654   }
655
656   is_popup_possibly_visible_ = true;
657   Send(new AutofillHostMsg_SetDataList(routing_id(),
658                                        data_list_values,
659                                        data_list_labels));
660
661   Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(),
662                                                   autofill_query_id_,
663                                                   form,
664                                                   field,
665                                                   bounding_box_scaled,
666                                                   display_warning_if_disabled));
667 }
668
669 void AutofillAgent::FillFieldWithValue(const base::string16& value,
670                                        WebInputElement* node) {
671   did_set_node_text_ = true;
672   node->setEditingValue(value.substr(0, node->maxLength()));
673   node->setAutofilled(true);
674 }
675
676 void AutofillAgent::PreviewFieldWithValue(const base::string16& value,
677                                           WebInputElement* node) {
678   was_query_node_autofilled_ = element_.isAutofilled();
679   node->setSuggestedValue(value.substr(0, node->maxLength()));
680   node->setAutofilled(true);
681   node->setSelectionRange(node->value().length(),
682                           node->suggestedValue().length());
683 }
684
685 void AutofillAgent::HidePopup() {
686   if (!is_popup_possibly_visible_)
687     return;
688
689   if (!element_.isNull())
690     OnClearPreviewedForm();
691
692   is_popup_possibly_visible_ = false;
693   Send(new AutofillHostMsg_HidePopup(routing_id()));
694 }
695
696 // TODO(isherman): Decide if we want to support non-password autofill with AJAX.
697 void AutofillAgent::didAssociateFormControls(const WebVector<WebNode>& nodes) {
698   for (size_t i = 0; i < nodes.size(); ++i) {
699     WebFrame* frame = nodes[i].document().frame();
700     // Only monitors dynamic forms created in the top frame. Dynamic forms
701     // inserted in iframes are not captured yet.
702     if (frame && !frame->parent()) {
703       password_autofill_agent_->OnDynamicFormsSeen(frame);
704       return;
705     }
706   }
707 }
708
709 }  // namespace autofill