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