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