Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(663)

Side by Side Diff: chrome/renderer/autofill/form_autofill_util.cc

Issue 11348273: [autofill] Fill in values on a successful run of interactive autocomplete. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: jhawkins@ review Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/renderer/autofill/form_autofill_util.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "chrome/renderer/autofill/form_autofill_util.h" 5 #include "chrome/renderer/autofill/form_autofill_util.h"
6 6
7 #include <map> 7 #include <map>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_vector.h" 10 #include "base/memory/scoped_vector.h"
(...skipping 395 matching lines...) Expand 10 before | Expand all | Expand 10 after
406 for (size_t i = 0; i < list_items.size(); ++i) { 406 for (size_t i = 0; i < list_items.size(); ++i) {
407 if (IsOptionElement(list_items[i])) { 407 if (IsOptionElement(list_items[i])) {
408 const WebOptionElement option = list_items[i].toConst<WebOptionElement>(); 408 const WebOptionElement option = list_items[i].toConst<WebOptionElement>();
409 option_values->push_back(option.value()); 409 option_values->push_back(option.value());
410 option_contents->push_back(option.text()); 410 option_contents->push_back(option.text());
411 } 411 }
412 } 412 }
413 } 413 }
414 414
415 // The callback type used by |ForEachMatchingFormField()|. 415 // The callback type used by |ForEachMatchingFormField()|.
416 typedef void (*Callback)(WebKit::WebFormControlElement*, 416 typedef void (*Callback)(const FormFieldData&,
417 const FormFieldData*, 417 bool, /* is_initiating_element */
418 bool); 418 WebKit::WebFormControlElement*);
419 419
420 // For each autofillable field in |data| that matches a field in the |form|, 420 // For each autofillable field in |data| that matches a field in the |form|,
421 // the |callback| is invoked with the corresponding |form| field data. 421 // the |callback| is invoked with the corresponding |form| field data.
422 void ForEachMatchingFormField(const WebFormElement& form_element, 422 void ForEachMatchingFormField(const WebFormElement& form_element,
423 const WebElement& initiating_element, 423 const WebElement& initiating_element,
424 const FormData& data, 424 const FormData& data,
425 bool only_focusable_elements,
425 Callback callback) { 426 Callback callback) {
426 std::vector<WebFormControlElement> control_elements; 427 std::vector<WebFormControlElement> control_elements;
427 ExtractAutofillableElements(form_element, autofill::REQUIRE_AUTOCOMPLETE, 428 ExtractAutofillableElements(form_element, autofill::REQUIRE_AUTOCOMPLETE,
428 &control_elements); 429 &control_elements);
429 430
430 if (control_elements.size() != data.fields.size()) { 431 if (control_elements.size() != data.fields.size()) {
431 // This case should be reachable only for pathological websites, which add 432 // This case should be reachable only for pathological websites, which add
432 // or remove form fields while the user is interacting with the Autofill 433 // or remove form fields while the user is interacting with the Autofill
433 // popup. I (isherman) am not aware of any such websites, and so am 434 // popup. I (isherman) am not aware of any such websites, and so am
434 // optimistically including a NOTREACHED(). If you ever trip this check, 435 // optimistically including a NOTREACHED(). If you ever trip this check,
(...skipping 24 matching lines...) Expand all
459 460
460 const WebInputElement* input_element = toWebInputElement(element); 461 const WebInputElement* input_element = toWebInputElement(element);
461 if (IsTextInput(input_element)) { 462 if (IsTextInput(input_element)) {
462 // Only autofill empty fields and the field that initiated the filling, 463 // Only autofill empty fields and the field that initiated the filling,
463 // i.e. the field the user is currently editing and interacting with. 464 // i.e. the field the user is currently editing and interacting with.
464 if (!is_initiating_element && !input_element->value().isEmpty()) 465 if (!is_initiating_element && !input_element->value().isEmpty())
465 continue; 466 continue;
466 } 467 }
467 468
468 if (!element->isEnabled() || element->isReadOnly() || 469 if (!element->isEnabled() || element->isReadOnly() ||
469 !element->isFocusable()) 470 (only_focusable_elements && !element->isFocusable()))
470 continue; 471 continue;
471 472
472 callback(element, &data.fields[i], is_initiating_element); 473 callback(data.fields[i], is_initiating_element, element);
473 } 474 }
474 } 475 }
475 476
476 // Sets the |field|'s value to the value in |data|. 477 // Sets the |field|'s value to the value in |data|.
477 // Also sets the "autofilled" attribute, causing the background to be yellow. 478 // Also sets the "autofilled" attribute, causing the background to be yellow.
478 void FillFormField(WebKit::WebFormControlElement* field, 479 void FillFormField(const FormFieldData& data,
479 const FormFieldData* data, 480 bool is_initiating_node,
480 bool is_initiating_node) { 481 WebKit::WebFormControlElement* field) {
481 // Nothing to fill. 482 // Nothing to fill.
482 if (data->value.empty()) 483 if (data.value.empty())
483 return; 484 return;
484 485
485 WebInputElement* input_element = toWebInputElement(field); 486 WebInputElement* input_element = toWebInputElement(field);
486 if (IsTextInput(input_element)) { 487 if (IsTextInput(input_element)) {
487 // If the maxlength attribute contains a negative value, maxLength() 488 // If the maxlength attribute contains a negative value, maxLength()
488 // returns the default maxlength value. 489 // returns the default maxlength value.
489 input_element->setValue( 490 input_element->setValue(
490 data->value.substr(0, input_element->maxLength()), true); 491 data.value.substr(0, input_element->maxLength()), true);
491 input_element->setAutofilled(true); 492 input_element->setAutofilled(true);
492 if (is_initiating_node) { 493 if (is_initiating_node) {
493 int length = input_element->value().length(); 494 int length = input_element->value().length();
494 input_element->setSelectionRange(length, length); 495 input_element->setSelectionRange(length, length);
495 // Clear the current IME composition (the underline), if there is one. 496 // Clear the current IME composition (the underline), if there is one.
496 input_element->document().frame()->unmarkText(); 497 input_element->document().frame()->unmarkText();
497 } 498 }
498 } else { 499 } else {
499 DCHECK(IsSelectElement(*field)); 500 DCHECK(IsSelectElement(*field));
500 WebSelectElement select_element = field->to<WebSelectElement>(); 501 WebSelectElement select_element = field->to<WebSelectElement>();
501 if (select_element.value() != data->value) { 502 if (select_element.value() != data.value) {
502 select_element.setValue(data->value); 503 select_element.setValue(data.value);
503 select_element.dispatchFormControlChangeEvent(); 504 select_element.dispatchFormControlChangeEvent();
504 } 505 }
505 } 506 }
506 } 507 }
507 508
508 // Sets the |field|'s "suggested" (non JS visible) value to the value in |data|. 509 // Sets the |field|'s "suggested" (non JS visible) value to the value in |data|.
509 // Also sets the "autofilled" attribute, causing the background to be yellow. 510 // Also sets the "autofilled" attribute, causing the background to be yellow.
510 void PreviewFormField(WebKit::WebFormControlElement* field, 511 void PreviewFormField(const FormFieldData& data,
511 const FormFieldData* data, 512 bool is_initiating_node,
512 bool is_initiating_node) { 513 WebKit::WebFormControlElement* field) {
513 // Nothing to preview. 514 // Nothing to preview.
514 if (data->value.empty()) 515 if (data.value.empty())
515 return; 516 return;
516 517
517 // Only preview input fields. 518 // Only preview input fields.
518 WebInputElement* input_element = toWebInputElement(field); 519 WebInputElement* input_element = toWebInputElement(field);
519 if (!IsTextInput(input_element)) 520 if (!IsTextInput(input_element))
520 return; 521 return;
521 522
522 // If the maxlength attribute contains a negative value, maxLength() 523 // If the maxlength attribute contains a negative value, maxLength()
523 // returns the default maxlength value. 524 // returns the default maxlength value.
524 input_element->setSuggestedValue( 525 input_element->setSuggestedValue(
525 data->value.substr(0, input_element->maxLength())); 526 data.value.substr(0, input_element->maxLength()));
526 input_element->setAutofilled(true); 527 input_element->setAutofilled(true);
527 if (is_initiating_node) { 528 if (is_initiating_node) {
528 // Select the part of the text that the user didn't type. 529 // Select the part of the text that the user didn't type.
529 input_element->setSelectionRange(input_element->value().length(), 530 input_element->setSelectionRange(input_element->value().length(),
530 input_element->suggestedValue().length()); 531 input_element->suggestedValue().length());
531 } 532 }
532 } 533 }
533 534
534 } // namespace 535 } // namespace
535 536
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after
813 } 814 }
814 815
815 void FillForm(const FormData& form, const WebInputElement& element) { 816 void FillForm(const FormData& form, const WebInputElement& element) {
816 WebFormElement form_element = element.form(); 817 WebFormElement form_element = element.form();
817 if (form_element.isNull()) 818 if (form_element.isNull())
818 return; 819 return;
819 820
820 ForEachMatchingFormField(form_element, 821 ForEachMatchingFormField(form_element,
821 element, 822 element,
822 form, 823 form,
824 true, /* only_focusable_elements */
823 &FillFormField); 825 &FillFormField);
824 } 826 }
825 827
828 void FillFormIncludingNonFocusableElements(const FormData& form_data,
829 const WebFormElement& form_element) {
830 if (form_element.isNull())
831 return;
832
833 ForEachMatchingFormField(form_element,
834 WebInputElement(),
835 form_data,
836 false, /* only_focusable_elements */
837 &FillFormField);
838 }
839
826 void PreviewForm(const FormData& form, const WebInputElement& element) { 840 void PreviewForm(const FormData& form, const WebInputElement& element) {
827 WebFormElement form_element = element.form(); 841 WebFormElement form_element = element.form();
828 if (form_element.isNull()) 842 if (form_element.isNull())
829 return; 843 return;
830 844
831 ForEachMatchingFormField(form_element, 845 ForEachMatchingFormField(form_element,
832 element, 846 element,
833 form, 847 form,
848 true, /* only_focusable_elements */
834 &PreviewFormField); 849 &PreviewFormField);
835 } 850 }
836 851
837 bool ClearPreviewedFormWithElement(const WebInputElement& element, 852 bool ClearPreviewedFormWithElement(const WebInputElement& element,
838 bool was_autofilled) { 853 bool was_autofilled) {
839 WebFormElement form_element = element.form(); 854 WebFormElement form_element = element.form();
840 if (form_element.isNull()) 855 if (form_element.isNull())
841 return false; 856 return false;
842 857
843 std::vector<WebFormControlElement> control_elements; 858 std::vector<WebFormControlElement> control_elements;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
896 continue; 911 continue;
897 912
898 if (input_element->isAutofilled()) 913 if (input_element->isAutofilled())
899 return true; 914 return true;
900 } 915 }
901 916
902 return false; 917 return false;
903 } 918 }
904 919
905 } // namespace autofill 920 } // namespace autofill
OLDNEW
« no previous file with comments | « chrome/renderer/autofill/form_autofill_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698