OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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 "components/autofill/content/renderer/autofill_agent.h" | 5 #include "components/autofill/content/renderer/autofill_agent.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
10 #include "base/strings/string_split.h" | 10 #include "base/strings/string_split.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 #include "third_party/WebKit/public/platform/WebURLRequest.h" | 34 #include "third_party/WebKit/public/platform/WebURLRequest.h" |
35 #include "third_party/WebKit/public/web/WebDataSource.h" | 35 #include "third_party/WebKit/public/web/WebDataSource.h" |
36 #include "third_party/WebKit/public/web/WebDocument.h" | 36 #include "third_party/WebKit/public/web/WebDocument.h" |
37 #include "third_party/WebKit/public/web/WebElementCollection.h" | 37 #include "third_party/WebKit/public/web/WebElementCollection.h" |
38 #include "third_party/WebKit/public/web/WebFormControlElement.h" | 38 #include "third_party/WebKit/public/web/WebFormControlElement.h" |
39 #include "third_party/WebKit/public/web/WebFormElement.h" | 39 #include "third_party/WebKit/public/web/WebFormElement.h" |
40 #include "third_party/WebKit/public/web/WebFrame.h" | 40 #include "third_party/WebKit/public/web/WebFrame.h" |
41 #include "third_party/WebKit/public/web/WebInputEvent.h" | 41 #include "third_party/WebKit/public/web/WebInputEvent.h" |
42 #include "third_party/WebKit/public/web/WebNode.h" | 42 #include "third_party/WebKit/public/web/WebNode.h" |
43 #include "third_party/WebKit/public/web/WebOptionElement.h" | 43 #include "third_party/WebKit/public/web/WebOptionElement.h" |
| 44 #include "third_party/WebKit/public/web/WebTextAreaElement.h" |
44 #include "third_party/WebKit/public/web/WebView.h" | 45 #include "third_party/WebKit/public/web/WebView.h" |
45 #include "ui/base/l10n/l10n_util.h" | 46 #include "ui/base/l10n/l10n_util.h" |
46 #include "ui/events/keycodes/keyboard_codes.h" | 47 #include "ui/events/keycodes/keyboard_codes.h" |
47 | 48 |
48 using blink::WebAutofillClient; | 49 using blink::WebAutofillClient; |
49 using blink::WebElement; | 50 using blink::WebElement; |
50 using blink::WebElementCollection; | 51 using blink::WebElementCollection; |
51 using blink::WebFormControlElement; | 52 using blink::WebFormControlElement; |
52 using blink::WebFormElement; | 53 using blink::WebFormElement; |
53 using blink::WebFrame; | 54 using blink::WebFrame; |
54 using blink::WebInputElement; | 55 using blink::WebInputElement; |
55 using blink::WebKeyboardEvent; | 56 using blink::WebKeyboardEvent; |
56 using blink::WebNode; | 57 using blink::WebNode; |
57 using blink::WebOptionElement; | 58 using blink::WebOptionElement; |
58 using blink::WebString; | 59 using blink::WebString; |
| 60 using blink::WebTextAreaElement; |
59 using blink::WebVector; | 61 using blink::WebVector; |
60 | 62 |
61 namespace autofill { | 63 namespace autofill { |
62 | 64 |
63 namespace { | 65 namespace { |
64 | 66 |
65 // Gets all the data list values (with corresponding label) for the given | 67 // Gets all the data list values (with corresponding label) for the given |
66 // element. | 68 // element. |
67 void GetDataListSuggestions(const WebInputElement& element, | 69 void GetDataListSuggestions(const WebInputElement& element, |
68 bool ignore_current_value, | 70 bool ignore_current_value, |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
289 HidePopup(); | 291 HidePopup(); |
290 | 292 |
291 in_flight_request_form_ = form; | 293 in_flight_request_form_ = form; |
292 Send(new AutofillHostMsg_RequestAutocomplete(routing_id(), form_data, url)); | 294 Send(new AutofillHostMsg_RequestAutocomplete(routing_id(), form_data, url)); |
293 } | 295 } |
294 | 296 |
295 void AutofillAgent::setIgnoreTextChanges(bool ignore) { | 297 void AutofillAgent::setIgnoreTextChanges(bool ignore) { |
296 ignore_text_changes_ = ignore; | 298 ignore_text_changes_ = ignore; |
297 } | 299 } |
298 | 300 |
299 void AutofillAgent::InputElementClicked(const WebInputElement& element, | 301 void AutofillAgent::FormControlElementClicked( |
300 bool was_focused, | 302 const WebFormControlElement& element, |
301 bool is_focused) { | 303 bool was_focused) { |
| 304 const WebInputElement* input_element = toWebInputElement(&element); |
| 305 if (!input_element && !IsTextAreaElement(element)) |
| 306 return; |
| 307 |
302 if (was_focused) | 308 if (was_focused) |
303 ShowSuggestions(element, true, false, true, false); | 309 ShowSuggestions(element, true, false, true, false); |
304 } | 310 } |
305 | 311 |
306 void AutofillAgent::InputElementLostFocus() { | 312 void AutofillAgent::FormControlElementLostFocus() { |
307 HidePopup(); | 313 HidePopup(); |
308 } | 314 } |
309 | 315 |
310 void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) { | 316 void AutofillAgent::textFieldDidEndEditing(const WebInputElement& element) { |
311 password_autofill_agent_->TextFieldDidEndEditing(element); | 317 password_autofill_agent_->TextFieldDidEndEditing(element); |
312 has_shown_autofill_popup_for_current_edit_ = false; | 318 has_shown_autofill_popup_for_current_edit_ = false; |
313 Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id())); | 319 Send(new AutofillHostMsg_DidEndTextFieldEditing(routing_id())); |
314 } | 320 } |
315 | 321 |
| 322 // TODO(ziran.sun): This function is to be removed once next Blink roll is done |
316 void AutofillAgent::textFieldDidChange(const WebInputElement& element) { | 323 void AutofillAgent::textFieldDidChange(const WebInputElement& element) { |
| 324 const WebFormControlElement control_element = |
| 325 element.toConst<WebFormControlElement>(); |
| 326 textFieldDidChange(control_element); |
| 327 } |
| 328 |
| 329 void AutofillAgent::textFieldDidChange(const WebFormControlElement& element) { |
317 if (ignore_text_changes_) | 330 if (ignore_text_changes_) |
318 return; | 331 return; |
319 | 332 |
| 333 DCHECK(toWebInputElement(&element) || IsTextAreaElement(element)); |
| 334 |
320 if (did_set_node_text_) { | 335 if (did_set_node_text_) { |
321 did_set_node_text_ = false; | 336 did_set_node_text_ = false; |
322 return; | 337 return; |
323 } | 338 } |
324 | 339 |
325 // We post a task for doing the Autofill as the caret position is not set | 340 // We post a task for doing the Autofill as the caret position is not set |
326 // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and | 341 // properly at this point (http://bugs.webkit.org/show_bug.cgi?id=16976) and |
327 // it is needed to trigger autofill. | 342 // it is needed to trigger autofill. |
328 weak_ptr_factory_.InvalidateWeakPtrs(); | 343 weak_ptr_factory_.InvalidateWeakPtrs(); |
329 base::MessageLoop::current()->PostTask( | 344 base::MessageLoop::current()->PostTask( |
330 FROM_HERE, | 345 FROM_HERE, |
331 base::Bind(&AutofillAgent::TextFieldDidChangeImpl, | 346 base::Bind(&AutofillAgent::TextFieldDidChangeImpl, |
332 weak_ptr_factory_.GetWeakPtr(), | 347 weak_ptr_factory_.GetWeakPtr(), |
333 element)); | 348 element)); |
334 } | 349 } |
335 | 350 |
336 void AutofillAgent::TextFieldDidChangeImpl(const WebInputElement& element) { | 351 void AutofillAgent::TextFieldDidChangeImpl( |
| 352 const WebFormControlElement& element) { |
337 // If the element isn't focused then the changes don't matter. This check is | 353 // If the element isn't focused then the changes don't matter. This check is |
338 // required to properly handle IME interactions. | 354 // required to properly handle IME interactions. |
339 if (!element.focused()) | 355 if (!element.focused()) |
340 return; | 356 return; |
341 | 357 |
342 if (password_generation_agent_ && | 358 const WebInputElement* input_element = toWebInputElement(&element); |
343 password_generation_agent_->TextDidChangeInTextField(element)) { | 359 if (input_element) { |
344 return; | 360 if (password_generation_agent_ && |
345 } | 361 password_generation_agent_->TextDidChangeInTextField(*input_element)) { |
| 362 return; |
| 363 } |
346 | 364 |
347 if (password_autofill_agent_->TextDidChangeInTextField(element)) { | 365 if (password_autofill_agent_->TextDidChangeInTextField(*input_element)) { |
348 element_ = element; | 366 element_ = element; |
349 return; | 367 return; |
| 368 } |
350 } | 369 } |
351 | 370 |
352 ShowSuggestions(element, false, true, false, false); | 371 ShowSuggestions(element, false, true, false, false); |
353 | 372 |
354 FormData form; | 373 FormData form; |
355 FormFieldData field; | 374 FormFieldData field; |
356 if (FindFormAndFieldForInputElement(element, &form, &field, REQUIRE_NONE)) { | 375 if (FindFormAndFieldForFormControlElement(element, |
| 376 &form, |
| 377 &field, |
| 378 REQUIRE_NONE)) { |
357 Send(new AutofillHostMsg_TextFieldDidChange(routing_id(), form, field, | 379 Send(new AutofillHostMsg_TextFieldDidChange(routing_id(), form, field, |
358 base::TimeTicks::Now())); | 380 base::TimeTicks::Now())); |
359 } | 381 } |
360 } | 382 } |
361 | 383 |
362 void AutofillAgent::textFieldDidReceiveKeyDown(const WebInputElement& element, | 384 void AutofillAgent::textFieldDidReceiveKeyDown(const WebInputElement& element, |
363 const WebKeyboardEvent& event) { | 385 const WebKeyboardEvent& event) { |
364 if (password_autofill_agent_->TextFieldHandlingKeyDown(element, event)) { | 386 if (password_autofill_agent_->TextFieldHandlingKeyDown(element, event)) { |
365 element_ = element; | 387 element_ = element; |
366 return; | 388 return; |
367 } | 389 } |
368 | 390 |
369 if (event.windowsKeyCode == ui::VKEY_DOWN || | 391 if (event.windowsKeyCode == ui::VKEY_DOWN || |
370 event.windowsKeyCode == ui::VKEY_UP) | 392 event.windowsKeyCode == ui::VKEY_UP) |
371 ShowSuggestions(element, true, true, true, false); | 393 ShowSuggestions(element, true, true, true, false); |
372 } | 394 } |
373 | 395 |
374 void AutofillAgent::openTextDataListChooser(const WebInputElement& element) { | 396 void AutofillAgent::openTextDataListChooser(const WebInputElement& element) { |
375 ShowSuggestions(element, true, false, false, true); | 397 ShowSuggestions(element, true, false, false, true); |
376 } | 398 } |
377 | 399 |
378 void AutofillAgent::AcceptDataListSuggestion( | 400 void AutofillAgent::AcceptDataListSuggestion( |
379 const base::string16& suggested_value) { | 401 const base::string16& suggested_value) { |
| 402 WebInputElement* input_element = toWebInputElement(&element_); |
| 403 DCHECK(input_element); |
380 base::string16 new_value = suggested_value; | 404 base::string16 new_value = suggested_value; |
381 // If this element takes multiple values then replace the last part with | 405 // If this element takes multiple values then replace the last part with |
382 // the suggestion. | 406 // the suggestion. |
383 if (element_.isMultiple() && | 407 if (input_element->isMultiple() && |
384 element_.formControlType() == WebString::fromUTF8("email")) { | 408 input_element->formControlType() == WebString::fromUTF8("email")) { |
385 std::vector<base::string16> parts; | 409 std::vector<base::string16> parts; |
386 | 410 |
387 base::SplitStringDontTrim(element_.editingValue(), ',', &parts); | 411 base::SplitStringDontTrim(input_element->editingValue(), ',', &parts); |
388 if (parts.size() == 0) | 412 if (parts.size() == 0) |
389 parts.push_back(base::string16()); | 413 parts.push_back(base::string16()); |
390 | 414 |
391 base::string16 last_part = parts.back(); | 415 base::string16 last_part = parts.back(); |
392 // We want to keep just the leading whitespace. | 416 // We want to keep just the leading whitespace. |
393 for (size_t i = 0; i < last_part.size(); ++i) { | 417 for (size_t i = 0; i < last_part.size(); ++i) { |
394 if (!IsWhitespace(last_part[i])) { | 418 if (!IsWhitespace(last_part[i])) { |
395 last_part = last_part.substr(0, i); | 419 last_part = last_part.substr(0, i); |
396 break; | 420 break; |
397 } | 421 } |
398 } | 422 } |
399 last_part.append(suggested_value); | 423 last_part.append(suggested_value); |
400 parts[parts.size() - 1] = last_part; | 424 parts[parts.size() - 1] = last_part; |
401 | 425 |
402 new_value = JoinString(parts, ','); | 426 new_value = JoinString(parts, ','); |
403 } | 427 } |
404 FillFieldWithValue(new_value, &element_); | 428 FillFieldWithValue(new_value, input_element); |
405 } | 429 } |
406 | 430 |
407 void AutofillAgent::OnFieldTypePredictionsAvailable( | 431 void AutofillAgent::OnFieldTypePredictionsAvailable( |
408 const std::vector<FormDataPredictions>& forms) { | 432 const std::vector<FormDataPredictions>& forms) { |
409 for (size_t i = 0; i < forms.size(); ++i) { | 433 for (size_t i = 0; i < forms.size(); ++i) { |
410 form_cache_.ShowPredictions(forms[i]); | 434 form_cache_.ShowPredictions(forms[i]); |
411 } | 435 } |
412 } | 436 } |
413 | 437 |
414 void AutofillAgent::OnFillForm(int query_id, const FormData& form) { | 438 void AutofillAgent::OnFillForm(int query_id, const FormData& form) { |
(...skipping 29 matching lines...) Expand all Loading... |
444 // TODO(isherman): There seem to be rare cases where this code *is* | 468 // TODO(isherman): There seem to be rare cases where this code *is* |
445 // reachable: see [ http://crbug.com/96321#c6 ]. Ideally we would | 469 // reachable: see [ http://crbug.com/96321#c6 ]. Ideally we would |
446 // understand those cases and fix the code to avoid them. However, so far I | 470 // understand those cases and fix the code to avoid them. However, so far I |
447 // have been unable to reproduce such a case locally. If you hit this | 471 // have been unable to reproduce such a case locally. If you hit this |
448 // NOTREACHED(), please file a bug against me. | 472 // NOTREACHED(), please file a bug against me. |
449 NOTREACHED(); | 473 NOTREACHED(); |
450 } | 474 } |
451 } | 475 } |
452 | 476 |
453 void AutofillAgent::OnFillFieldWithValue(const base::string16& value) { | 477 void AutofillAgent::OnFillFieldWithValue(const base::string16& value) { |
454 FillFieldWithValue(value, &element_); | 478 WebInputElement* input_element = toWebInputElement(&element_); |
| 479 if (input_element) |
| 480 FillFieldWithValue(value, input_element); |
455 } | 481 } |
456 | 482 |
457 void AutofillAgent::OnPreviewFieldWithValue(const base::string16& value) { | 483 void AutofillAgent::OnPreviewFieldWithValue(const base::string16& value) { |
458 PreviewFieldWithValue(value, &element_); | 484 WebInputElement* input_element = toWebInputElement(&element_); |
| 485 if (input_element) |
| 486 PreviewFieldWithValue(value, input_element); |
459 } | 487 } |
460 | 488 |
461 void AutofillAgent::OnAcceptDataListSuggestion(const base::string16& value) { | 489 void AutofillAgent::OnAcceptDataListSuggestion(const base::string16& value) { |
462 AcceptDataListSuggestion(value); | 490 AcceptDataListSuggestion(value); |
463 } | 491 } |
464 | 492 |
465 void AutofillAgent::OnAcceptPasswordAutofillSuggestion( | 493 void AutofillAgent::OnAcceptPasswordAutofillSuggestion( |
466 const base::string16& username) { | 494 const base::string16& username) { |
467 // We need to make sure this is handled here because the browser process | 495 // We need to make sure this is handled here because the browser process |
468 // skipped it handling because it believed it would be handled here. If it | 496 // skipped it handling because it believed it would be handled here. If it |
(...skipping 13 matching lines...) Expand all Loading... |
482 if (result == WebFormElement::AutocompleteResultSuccess) { | 510 if (result == WebFormElement::AutocompleteResultSuccess) { |
483 FillFormIncludingNonFocusableElements(form_data, in_flight_request_form_); | 511 FillFormIncludingNonFocusableElements(form_data, in_flight_request_form_); |
484 if (!in_flight_request_form_.checkValidityWithoutDispatchingEvents()) | 512 if (!in_flight_request_form_.checkValidityWithoutDispatchingEvents()) |
485 result = WebFormElement::AutocompleteResultErrorInvalid; | 513 result = WebFormElement::AutocompleteResultErrorInvalid; |
486 } | 514 } |
487 | 515 |
488 in_flight_request_form_.finishRequestAutocomplete(result); | 516 in_flight_request_form_.finishRequestAutocomplete(result); |
489 in_flight_request_form_.reset(); | 517 in_flight_request_form_.reset(); |
490 } | 518 } |
491 | 519 |
492 void AutofillAgent::ShowSuggestions(const WebInputElement& element, | 520 void AutofillAgent::ShowSuggestions(const WebFormControlElement& element, |
493 bool autofill_on_empty_values, | 521 bool autofill_on_empty_values, |
494 bool requires_caret_at_end, | 522 bool requires_caret_at_end, |
495 bool display_warning_if_disabled, | 523 bool display_warning_if_disabled, |
496 bool datalist_only) { | 524 bool datalist_only) { |
497 if (!element.isEnabled() || element.isReadOnly() || !element.isTextField() || | 525 if (!element.isEnabled() || element.isReadOnly()) |
498 element.isPasswordField()) | |
499 return; | 526 return; |
500 if (!datalist_only && !element.suggestedValue().isEmpty()) | 527 |
501 return; | 528 const WebInputElement* input_element = toWebInputElement(&element); |
| 529 if (input_element) { |
| 530 if (!input_element->isTextField() || input_element->isPasswordField()) |
| 531 return; |
| 532 if (!datalist_only && !input_element->suggestedValue().isEmpty()) |
| 533 return; |
| 534 } else { |
| 535 DCHECK(IsTextAreaElement(element)); |
| 536 if (!element.toConst<WebTextAreaElement>().suggestedValue().isEmpty()) |
| 537 return; |
| 538 } |
502 | 539 |
503 // Don't attempt to autofill with values that are too large or if filling | 540 // Don't attempt to autofill with values that are too large or if filling |
504 // criteria are not met. | 541 // criteria are not met. |
505 WebString value = element.editingValue(); | 542 WebString value = element.editingValue(); |
506 if (!datalist_only && | 543 if (!datalist_only && |
507 (value.length() > kMaxDataLength || | 544 (value.length() > kMaxDataLength || |
508 (!autofill_on_empty_values && value.isEmpty()) || | 545 (!autofill_on_empty_values && value.isEmpty()) || |
509 (requires_caret_at_end && | 546 (requires_caret_at_end && |
510 (element.selectionStart() != element.selectionEnd() || | 547 (element.selectionStart() != element.selectionEnd() || |
511 element.selectionEnd() != static_cast<int>(value.length()))))) { | 548 element.selectionEnd() != static_cast<int>(value.length()))))) { |
512 // Any popup currently showing is obsolete. | 549 // Any popup currently showing is obsolete. |
513 HidePopup(); | 550 HidePopup(); |
514 return; | 551 return; |
515 } | 552 } |
516 | 553 |
517 element_ = element; | 554 element_ = element; |
518 if (password_autofill_agent_->ShowSuggestions(element)) { | 555 if (input_element && |
| 556 password_autofill_agent_->ShowSuggestions(*input_element)) { |
519 is_popup_possibly_visible_ = true; | 557 is_popup_possibly_visible_ = true; |
520 return; | 558 return; |
521 } | 559 } |
522 | 560 |
523 // If autocomplete is disabled at the field level, ensure that the native | 561 // If autocomplete is disabled at the field level, ensure that the native |
524 // UI won't try to show a warning, since that may conflict with a custom | 562 // UI won't try to show a warning, since that may conflict with a custom |
525 // popup. Note that we cannot use the WebKit method element.autoComplete() | 563 // popup. Note that we cannot use the WebKit method element.autoComplete() |
526 // as it does not allow us to distinguish the case where autocomplete is | 564 // as it does not allow us to distinguish the case where autocomplete is |
527 // disabled for *both* the element and for the form. | 565 // disabled for *both* the element and for the form. |
528 const base::string16 autocomplete_attribute = | 566 const base::string16 autocomplete_attribute = |
529 element.getAttribute("autocomplete"); | 567 element.getAttribute("autocomplete"); |
530 if (LowerCaseEqualsASCII(autocomplete_attribute, "off")) | 568 if (LowerCaseEqualsASCII(autocomplete_attribute, "off")) |
531 display_warning_if_disabled = false; | 569 display_warning_if_disabled = false; |
532 | 570 |
533 QueryAutofillSuggestions(element, | 571 QueryAutofillSuggestions(element, |
534 display_warning_if_disabled, | 572 display_warning_if_disabled, |
535 datalist_only); | 573 datalist_only); |
536 } | 574 } |
537 | 575 |
538 void AutofillAgent::QueryAutofillSuggestions(const WebInputElement& element, | 576 void AutofillAgent::QueryAutofillSuggestions( |
539 bool display_warning_if_disabled, | 577 const WebFormControlElement& element, |
540 bool datalist_only) { | 578 bool display_warning_if_disabled, |
| 579 bool datalist_only) { |
541 if (!element.document().frame()) | 580 if (!element.document().frame()) |
542 return; | 581 return; |
543 | 582 |
| 583 DCHECK(toWebInputElement(&element) || IsTextAreaElement(element)); |
| 584 |
544 static int query_counter = 0; | 585 static int query_counter = 0; |
545 autofill_query_id_ = query_counter++; | 586 autofill_query_id_ = query_counter++; |
546 display_warning_if_disabled_ = display_warning_if_disabled; | 587 display_warning_if_disabled_ = display_warning_if_disabled; |
547 | 588 |
548 // If autocomplete is disabled at the form level, we want to see if there | 589 // If autocomplete is disabled at the form level, we want to see if there |
549 // would have been any suggestions were it enabled, so that we can show a | 590 // would have been any suggestions were it enabled, so that we can show a |
550 // warning. Otherwise, we want to ignore fields that disable autocomplete, so | 591 // warning. Otherwise, we want to ignore fields that disable autocomplete, so |
551 // that the suggestions list does not include suggestions for these form | 592 // that the suggestions list does not include suggestions for these form |
552 // fields -- see comment 1 on http://crbug.com/69914 | 593 // fields -- see comment 1 on http://crbug.com/69914 |
553 const RequirementsMask requirements = | 594 const RequirementsMask requirements = |
554 element.autoComplete() ? REQUIRE_AUTOCOMPLETE : REQUIRE_NONE; | 595 element.autoComplete() ? REQUIRE_AUTOCOMPLETE : REQUIRE_NONE; |
555 | 596 |
556 FormData form; | 597 FormData form; |
557 FormFieldData field; | 598 FormFieldData field; |
558 if (!FindFormAndFieldForInputElement(element, &form, &field, requirements)) { | 599 if (!FindFormAndFieldForFormControlElement(element, &form, &field, |
| 600 requirements)) { |
559 // If we didn't find the cached form, at least let autocomplete have a shot | 601 // If we didn't find the cached form, at least let autocomplete have a shot |
560 // at providing suggestions. | 602 // at providing suggestions. |
561 WebFormControlElementToFormField(element, EXTRACT_VALUE, &field); | 603 WebFormControlElementToFormField(element, EXTRACT_VALUE, &field); |
562 } | 604 } |
563 if (datalist_only) | 605 if (datalist_only) |
564 field.should_autocomplete = false; | 606 field.should_autocomplete = false; |
565 | 607 |
566 gfx::RectF bounding_box_scaled = | 608 gfx::RectF bounding_box_scaled = |
567 GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_); | 609 GetScaledBoundingBox(web_view_->pageScaleFactor(), &element_); |
568 | 610 |
569 // Find the datalist values and send them to the browser process. | 611 const WebInputElement* input_element = toWebInputElement(&element); |
570 std::vector<base::string16> data_list_values; | 612 if (input_element) { |
571 std::vector<base::string16> data_list_labels; | 613 // Find the datalist values and send them to the browser process. |
572 GetDataListSuggestions(element_, | 614 std::vector<base::string16> data_list_values; |
573 datalist_only, | 615 std::vector<base::string16> data_list_labels; |
574 &data_list_values, | 616 GetDataListSuggestions(*input_element, |
575 &data_list_labels); | 617 datalist_only, |
576 TrimStringVectorForIPC(&data_list_values); | 618 &data_list_values, |
577 TrimStringVectorForIPC(&data_list_labels); | 619 &data_list_labels); |
| 620 TrimStringVectorForIPC(&data_list_values); |
| 621 TrimStringVectorForIPC(&data_list_labels); |
| 622 |
| 623 Send(new AutofillHostMsg_SetDataList(routing_id(), |
| 624 data_list_values, |
| 625 data_list_labels)); |
| 626 } |
578 | 627 |
579 is_popup_possibly_visible_ = true; | 628 is_popup_possibly_visible_ = true; |
580 Send(new AutofillHostMsg_SetDataList(routing_id(), | |
581 data_list_values, | |
582 data_list_labels)); | |
583 | |
584 Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(), | 629 Send(new AutofillHostMsg_QueryFormFieldAutofill(routing_id(), |
585 autofill_query_id_, | 630 autofill_query_id_, |
586 form, | 631 form, |
587 field, | 632 field, |
588 bounding_box_scaled, | 633 bounding_box_scaled, |
589 display_warning_if_disabled)); | 634 display_warning_if_disabled)); |
590 } | 635 } |
591 | 636 |
592 void AutofillAgent::FillFieldWithValue(const base::string16& value, | 637 void AutofillAgent::FillFieldWithValue(const base::string16& value, |
593 WebInputElement* node) { | 638 WebInputElement* node) { |
(...skipping 27 matching lines...) Expand all Loading... |
621 // Only monitors dynamic forms created in the top frame. Dynamic forms | 666 // Only monitors dynamic forms created in the top frame. Dynamic forms |
622 // inserted in iframes are not captured yet. | 667 // inserted in iframes are not captured yet. |
623 if (frame && !frame->parent()) { | 668 if (frame && !frame->parent()) { |
624 password_autofill_agent_->OnDynamicFormsSeen(frame); | 669 password_autofill_agent_->OnDynamicFormsSeen(frame); |
625 return; | 670 return; |
626 } | 671 } |
627 } | 672 } |
628 } | 673 } |
629 | 674 |
630 } // namespace autofill | 675 } // namespace autofill |
OLD | NEW |