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