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