OLD | NEW |
---|---|
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/form_manager.h" | 5 #include "chrome/renderer/form_manager.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/scoped_vector.h" | 8 #include "base/scoped_vector.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "base/stl_util-inl.h" | 10 #include "base/stl_util-inl.h" |
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 // For select-one elements copy option strings. | 266 // For select-one elements copy option strings. |
267 WebVector<WebElement> list_items = select_element.listItems(); | 267 WebVector<WebElement> list_items = select_element.listItems(); |
268 option_strings->reserve(list_items.size()); | 268 option_strings->reserve(list_items.size()); |
269 for (size_t i = 0; i < list_items.size(); ++i) { | 269 for (size_t i = 0; i < list_items.size(); ++i) { |
270 if (list_items[i].hasTagName("option")) | 270 if (list_items[i].hasTagName("option")) |
271 option_strings->push_back(list_items[i].to<WebOptionElement>().value()); | 271 option_strings->push_back(list_items[i].to<WebOptionElement>().value()); |
272 } | 272 } |
273 } | 273 } |
274 } | 274 } |
275 | 275 |
276 // In HTML5, email,month and tel are text input field to autocomplete. | |
James Hawkins
2011/01/03 19:50:00
space after comma
| |
277 static bool IsTextInput(const WebFormControlElement& element) { | |
278 const static char* type_names[] = {"text", "email", "tel", "month"}; | |
279 for (size_t i = 0; i < sizeof(type_names)/sizeof(const char*); ++i) { | |
280 if (element.formControlType() == WebString::fromUTF8(type_names[i])) | |
281 return true; | |
282 } | |
283 return false; | |
284 } | |
285 | |
276 } // namespace | 286 } // namespace |
277 | 287 |
278 struct FormManager::FormElement { | 288 struct FormManager::FormElement { |
279 WebKit::WebFormElement form_element; | 289 WebKit::WebFormElement form_element; |
280 std::vector<WebKit::WebFormControlElement> control_elements; | 290 std::vector<WebKit::WebFormControlElement> control_elements; |
281 std::vector<string16> control_values; | 291 std::vector<string16> control_values; |
282 }; | 292 }; |
283 | 293 |
284 FormManager::FormManager() { | 294 FormManager::FormManager() { |
285 } | 295 } |
(...skipping 15 matching lines...) Expand all Loading... | |
301 field->set_name(element.nameForAutofill()); | 311 field->set_name(element.nameForAutofill()); |
302 field->set_form_control_type(element.formControlType()); | 312 field->set_form_control_type(element.formControlType()); |
303 | 313 |
304 if (extract_mask & EXTRACT_OPTIONS) { | 314 if (extract_mask & EXTRACT_OPTIONS) { |
305 // Set option strings on the field if available. | 315 // Set option strings on the field if available. |
306 std::vector<string16> option_strings; | 316 std::vector<string16> option_strings; |
307 GetOptionStringsFromElement(element, &option_strings); | 317 GetOptionStringsFromElement(element, &option_strings); |
308 field->set_option_strings(option_strings); | 318 field->set_option_strings(option_strings); |
309 } | 319 } |
310 | 320 |
311 if (element.formControlType() == WebString::fromUTF8("text")) { | 321 if (IsTextInput(element)) { |
312 const WebInputElement& input_element = element.toConst<WebInputElement>(); | 322 const WebInputElement& input_element = element.toConst<WebInputElement>(); |
313 field->set_max_length(input_element.maxLength()); | 323 field->set_max_length(input_element.maxLength()); |
314 field->set_autofilled(input_element.isAutofilled()); | 324 field->set_autofilled(input_element.isAutofilled()); |
315 } | 325 } |
316 | 326 |
317 if (!(extract_mask & EXTRACT_VALUE)) | 327 if (!(extract_mask & EXTRACT_VALUE)) |
318 return; | 328 return; |
319 | 329 |
320 // TODO(jhawkins): In WebKit, move value() and setValue() to | 330 // TODO(jhawkins): In WebKit, move value() and setValue() to |
321 // WebFormControlElement. | 331 // WebFormControlElement. |
322 string16 value; | 332 string16 value; |
323 if (element.formControlType() == WebString::fromUTF8("text") || | 333 if (IsTextInput(element) || |
324 element.formControlType() == WebString::fromUTF8("hidden")) { | 334 element.formControlType() == WebString::fromUTF8("hidden")) { |
325 const WebInputElement& input_element = | 335 const WebInputElement& input_element = |
326 element.toConst<WebInputElement>(); | 336 element.toConst<WebInputElement>(); |
327 value = input_element.value(); | 337 value = input_element.value(); |
328 } else if (element.formControlType() == WebString::fromUTF8("select-one")) { | 338 } else if (element.formControlType() == WebString::fromUTF8("select-one")) { |
329 // TODO(jhawkins): This is ugly. WebSelectElement::value() is a non-const | 339 // TODO(jhawkins): This is ugly. WebSelectElement::value() is a non-const |
330 // method. Look into fixing this on the WebKit side. | 340 // method. Look into fixing this on the WebKit side. |
331 WebFormControlElement& e = const_cast<WebFormControlElement&>(element); | 341 WebFormControlElement& e = const_cast<WebFormControlElement&>(element); |
332 WebSelectElement select_element = e.to<WebSelectElement>(); | 342 WebSelectElement select_element = e.to<WebSelectElement>(); |
333 value = select_element.value(); | 343 value = select_element.value(); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
410 WebVector<WebFormControlElement> control_elements; | 420 WebVector<WebFormControlElement> control_elements; |
411 element.getFormControlElements(control_elements); | 421 element.getFormControlElements(control_elements); |
412 | 422 |
413 // A vector of bools that indicate whether each field in the form meets the | 423 // A vector of bools that indicate whether each field in the form meets the |
414 // requirements and thus will be in the resulting |form|. | 424 // requirements and thus will be in the resulting |form|. |
415 std::vector<bool> fields_extracted(control_elements.size(), false); | 425 std::vector<bool> fields_extracted(control_elements.size(), false); |
416 | 426 |
417 for (size_t i = 0; i < control_elements.size(); ++i) { | 427 for (size_t i = 0; i < control_elements.size(); ++i) { |
418 const WebFormControlElement& control_element = control_elements[i]; | 428 const WebFormControlElement& control_element = control_elements[i]; |
419 | 429 |
420 if (requirements & REQUIRE_AUTOCOMPLETE && | 430 if (requirements & REQUIRE_AUTOCOMPLETE && IsTextInput(control_element)) { |
421 control_element.formControlType() == WebString::fromUTF8("text")) { | |
422 const WebInputElement& input_element = | 431 const WebInputElement& input_element = |
423 control_element.toConst<WebInputElement>(); | 432 control_element.toConst<WebInputElement>(); |
424 if (!input_element.autoComplete()) | 433 if (!input_element.autoComplete()) |
425 continue; | 434 continue; |
426 } | 435 } |
427 | 436 |
428 if (requirements & REQUIRE_ENABLED && !control_element.isEnabled()) | 437 if (requirements & REQUIRE_ENABLED && !control_element.isEnabled()) |
429 continue; | 438 continue; |
430 | 439 |
431 // Create a new FormField, fill it out and map it to the field's name. | 440 // Create a new FormField, fill it out and map it to the field's name. |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
624 return true; | 633 return true; |
625 } | 634 } |
626 | 635 |
627 bool FormManager::ClearFormWithNode(const WebNode& node) { | 636 bool FormManager::ClearFormWithNode(const WebNode& node) { |
628 FormElement* form_element = NULL; | 637 FormElement* form_element = NULL; |
629 if (!FindCachedFormElementWithNode(node, &form_element)) | 638 if (!FindCachedFormElementWithNode(node, &form_element)) |
630 return false; | 639 return false; |
631 | 640 |
632 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { | 641 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { |
633 WebFormControlElement element = form_element->control_elements[i]; | 642 WebFormControlElement element = form_element->control_elements[i]; |
634 if (element.formControlType() == WebString::fromUTF8("text")) { | 643 if (IsTextInput(element)) { |
635 | 644 |
636 WebInputElement input_element = element.to<WebInputElement>(); | 645 WebInputElement input_element = element.to<WebInputElement>(); |
637 | 646 |
638 // We don't modify the value of disabled fields. | 647 // We don't modify the value of disabled fields. |
639 if (!input_element.isEnabled()) | 648 if (!input_element.isEnabled()) |
640 continue; | 649 continue; |
641 | 650 |
642 input_element.setValue(string16()); | 651 input_element.setValue(string16()); |
643 input_element.setAutofilled(false); | 652 input_element.setAutofilled(false); |
644 | 653 |
(...skipping 15 matching lines...) Expand all Loading... | |
660 bool FormManager::ClearPreviewedFormWithNode(const WebNode& node, | 669 bool FormManager::ClearPreviewedFormWithNode(const WebNode& node, |
661 bool was_autofilled) { | 670 bool was_autofilled) { |
662 FormElement* form_element = NULL; | 671 FormElement* form_element = NULL; |
663 if (!FindCachedFormElementWithNode(node, &form_element)) | 672 if (!FindCachedFormElementWithNode(node, &form_element)) |
664 return false; | 673 return false; |
665 | 674 |
666 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { | 675 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { |
667 WebFormControlElement* element = &form_element->control_elements[i]; | 676 WebFormControlElement* element = &form_element->control_elements[i]; |
668 | 677 |
669 // Only input elements can be previewed. | 678 // Only input elements can be previewed. |
670 if (element->formControlType() != WebString::fromUTF8("text")) | 679 if (!IsTextInput(*element)) |
671 continue; | 680 continue; |
672 | 681 |
673 // If the input element has not been auto-filled, FormManager has not | 682 // If the input element has not been auto-filled, FormManager has not |
674 // previewed this field, so we have nothing to reset. | 683 // previewed this field, so we have nothing to reset. |
675 WebInputElement input_element = element->to<WebInputElement>(); | 684 WebInputElement input_element = element->to<WebInputElement>(); |
676 if (!input_element.isAutofilled()) | 685 if (!input_element.isAutofilled()) |
677 continue; | 686 continue; |
678 | 687 |
679 // There might be unrelated elements in this form which have already been | 688 // There might be unrelated elements in this form which have already been |
680 // auto-filled. For example, the user might have already filled the address | 689 // auto-filled. For example, the user might have already filled the address |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
724 } | 733 } |
725 } | 734 } |
726 | 735 |
727 bool FormManager::FormWithNodeIsAutoFilled(const WebNode& node) { | 736 bool FormManager::FormWithNodeIsAutoFilled(const WebNode& node) { |
728 FormElement* form_element = NULL; | 737 FormElement* form_element = NULL; |
729 if (!FindCachedFormElementWithNode(node, &form_element)) | 738 if (!FindCachedFormElementWithNode(node, &form_element)) |
730 return false; | 739 return false; |
731 | 740 |
732 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { | 741 for (size_t i = 0; i < form_element->control_elements.size(); ++i) { |
733 WebFormControlElement element = form_element->control_elements[i]; | 742 WebFormControlElement element = form_element->control_elements[i]; |
734 if (element.formControlType() != WebString::fromUTF8("text")) | 743 if (!IsTextInput(element)) |
735 continue; | 744 continue; |
736 | 745 |
737 const WebInputElement& input_element = element.to<WebInputElement>(); | 746 const WebInputElement& input_element = element.to<WebInputElement>(); |
738 if (input_element.isAutofilled()) | 747 if (input_element.isAutofilled()) |
739 return true; | 748 return true; |
740 } | 749 } |
741 | 750 |
742 return false; | 751 return false; |
743 } | 752 } |
744 | 753 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
837 if (k >= data.fields.size()) | 846 if (k >= data.fields.size()) |
838 continue; | 847 continue; |
839 | 848 |
840 DCHECK_EQ(data.fields[k].name(), element_name); | 849 DCHECK_EQ(data.fields[k].name(), element_name); |
841 | 850 |
842 bool is_initiating_node = false; | 851 bool is_initiating_node = false; |
843 | 852 |
844 // More than likely |requirements| will contain REQUIRE_AUTOCOMPLETE and/or | 853 // More than likely |requirements| will contain REQUIRE_AUTOCOMPLETE and/or |
845 // REQUIRE_EMPTY, which both require text form control elements, so special- | 854 // REQUIRE_EMPTY, which both require text form control elements, so special- |
846 // case this type of element. | 855 // case this type of element. |
847 if (element->formControlType() == WebString::fromUTF8("text")) { | 856 if (IsTextInput(*element)) { |
848 const WebInputElement& input_element = | 857 const WebInputElement& input_element = |
849 element->toConst<WebInputElement>(); | 858 element->toConst<WebInputElement>(); |
850 | 859 |
851 // TODO(jhawkins): WebKit currently doesn't handle the autocomplete | 860 // TODO(jhawkins): WebKit currently doesn't handle the autocomplete |
852 // attribute for select control elements, but it probably should. | 861 // attribute for select control elements, but it probably should. |
853 if (requirements & REQUIRE_AUTOCOMPLETE && !input_element.autoComplete()) | 862 if (requirements & REQUIRE_AUTOCOMPLETE && !input_element.autoComplete()) |
854 continue; | 863 continue; |
855 | 864 |
856 is_initiating_node = (input_element == node); | 865 is_initiating_node = (input_element == node); |
857 // Don't require the node that initiated the auto-fill process to be | 866 // Don't require the node that initiated the auto-fill process to be |
(...skipping 17 matching lines...) Expand all Loading... | |
875 delete callback; | 884 delete callback; |
876 } | 885 } |
877 | 886 |
878 void FormManager::FillFormField(WebFormControlElement* field, | 887 void FormManager::FillFormField(WebFormControlElement* field, |
879 const FormField* data, | 888 const FormField* data, |
880 bool is_initiating_node) { | 889 bool is_initiating_node) { |
881 // Nothing to fill. | 890 // Nothing to fill. |
882 if (data->value().empty()) | 891 if (data->value().empty()) |
883 return; | 892 return; |
884 | 893 |
885 if (field->formControlType() == WebString::fromUTF8("text")) { | 894 if (IsTextInput(*field)) { |
886 WebInputElement input_element = field->to<WebInputElement>(); | 895 WebInputElement input_element = field->to<WebInputElement>(); |
887 | 896 |
888 // If the maxlength attribute contains a negative value, maxLength() | 897 // If the maxlength attribute contains a negative value, maxLength() |
889 // returns the default maxlength value. | 898 // returns the default maxlength value. |
890 input_element.setValue(data->value().substr(0, input_element.maxLength())); | 899 input_element.setValue(data->value().substr(0, input_element.maxLength())); |
891 input_element.setAutofilled(true); | 900 input_element.setAutofilled(true); |
892 if (is_initiating_node) { | 901 if (is_initiating_node) { |
893 int length = input_element.value().length(); | 902 int length = input_element.value().length(); |
894 input_element.setSelectionRange(length, length); | 903 input_element.setSelectionRange(length, length); |
895 } | 904 } |
896 } else if (field->formControlType() == WebString::fromUTF8("select-one")) { | 905 } else if (field->formControlType() == WebString::fromUTF8("select-one")) { |
897 WebSelectElement select_element = field->to<WebSelectElement>(); | 906 WebSelectElement select_element = field->to<WebSelectElement>(); |
898 select_element.setValue(data->value()); | 907 select_element.setValue(data->value()); |
899 } | 908 } |
900 } | 909 } |
901 | 910 |
902 void FormManager::PreviewFormField(WebFormControlElement* field, | 911 void FormManager::PreviewFormField(WebFormControlElement* field, |
903 const FormField* data, | 912 const FormField* data, |
904 bool is_initiating_node) { | 913 bool is_initiating_node) { |
905 // Nothing to preview. | 914 // Nothing to preview. |
906 if (data->value().empty()) | 915 if (data->value().empty()) |
907 return; | 916 return; |
908 | 917 |
909 // Only preview input fields. | 918 // Only preview input fields. |
910 if (field->formControlType() != WebString::fromUTF8("text")) | 919 if (!IsTextInput(*field)) |
911 return; | 920 return; |
912 | 921 |
913 WebInputElement input_element = field->to<WebInputElement>(); | 922 WebInputElement input_element = field->to<WebInputElement>(); |
914 | 923 |
915 // If the maxlength attribute contains a negative value, maxLength() | 924 // If the maxlength attribute contains a negative value, maxLength() |
916 // returns the default maxlength value. | 925 // returns the default maxlength value. |
917 input_element.setSuggestedValue( | 926 input_element.setSuggestedValue( |
918 data->value().substr(0, input_element.maxLength())); | 927 data->value().substr(0, input_element.maxLength())); |
919 input_element.setAutofilled(true); | 928 input_element.setAutofilled(true); |
920 if (is_initiating_node) | 929 if (is_initiating_node) |
921 input_element.setSelectionRange(0, input_element.suggestedValue().length()); | 930 input_element.setSelectionRange(0, input_element.suggestedValue().length()); |
922 } | 931 } |
OLD | NEW |